mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
【sa-token】登录和退出换写法
This commit is contained in:
@ -7,8 +7,8 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
import org.jeecg.common.util.LoginUserUtils;
|
||||||
import org.jeecg.common.util.RedisUtil;
|
import org.jeecg.common.util.RedisUtil;
|
||||||
import org.jeecg.modules.cas.util.CasServiceUtil;
|
import org.jeecg.modules.cas.util.CasServiceUtil;
|
||||||
import org.jeecg.modules.cas.util.XmlUtils;
|
import org.jeecg.modules.cas.util.XmlUtils;
|
||||||
@ -16,6 +16,7 @@ import org.jeecg.modules.system.entity.SysDepart;
|
|||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
import org.jeecg.modules.system.service.ISysDepartService;
|
import org.jeecg.modules.system.service.ISysDepartService;
|
||||||
import org.jeecg.modules.system.service.ISysUserService;
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
@ -78,10 +79,10 @@ public class CasClientController {
|
|||||||
if(!result.isSuccess()) {
|
if(!result.isSuccess()) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword());
|
// 使用Sa-Token生成token(使用username作为loginId)
|
||||||
// 设置超时时间
|
LoginUser loginUser = new LoginUser();
|
||||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
BeanUtils.copyProperties(sysUser, loginUser);
|
||||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
String token = LoginUserUtils.doLogin(loginUser);
|
||||||
|
|
||||||
//获取用户部门信息
|
//获取用户部门信息
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
|
|||||||
@ -6,10 +6,12 @@ import org.apache.commons.lang3.ObjectUtils;
|
|||||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.LoginUserUtils;
|
||||||
import org.jeecg.common.util.RedisUtil;
|
import org.jeecg.common.util.RedisUtil;
|
||||||
import org.jeecg.common.util.SpringContextUtils;
|
import org.jeecg.common.util.SpringContextUtils;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.jeecg.config.StaticConfig;
|
import org.jeecg.config.StaticConfig;
|
||||||
import org.jeecg.modules.message.entity.SysMessage;
|
import org.jeecg.modules.message.entity.SysMessage;
|
||||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||||
@ -240,12 +242,10 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getToken(SysUser user) {
|
private String getToken(SysUser user) {
|
||||||
// 生成token
|
// 使用封装方法:一步完成登录和设置用户信息
|
||||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
|
LoginUser loginUser = new LoginUser();
|
||||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
BeanUtils.copyProperties(user, loginUser);
|
||||||
// 设置超时时间 1个小时
|
return LoginUserUtils.doLogin(loginUser);
|
||||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000);
|
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,11 +7,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.system.base.controller.JeecgController;
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.LoginUserUtils;
|
||||||
import org.jeecg.common.util.RedisUtil;
|
import org.jeecg.common.util.RedisUtil;
|
||||||
import org.jeecg.common.util.RestUtil;
|
import org.jeecg.common.util.RestUtil;
|
||||||
import org.jeecg.modules.openapi.entity.OpenApi;
|
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||||
@ -24,6 +26,7 @@ import org.jeecg.modules.openapi.service.OpenApiService;
|
|||||||
import org.jeecg.modules.openapi.swagger.*;
|
import org.jeecg.modules.openapi.swagger.*;
|
||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
import org.jeecg.modules.system.service.ISysUserService;
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
@ -33,7 +36,6 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -163,7 +165,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
|
|||||||
String appkey = request.getHeader("appkey");
|
String appkey = request.getHeader("appkey");
|
||||||
OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey);
|
OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey);
|
||||||
SysUser systemUser = sysUserService.getUserByName(openApiAuth.getCreateBy());
|
SysUser systemUser = sysUserService.getUserByName(openApiAuth.getCreateBy());
|
||||||
String token = this.getToken(systemUser.getUsername(), systemUser.getPassword());
|
String token = this.getToken(systemUser);
|
||||||
httpHeaders.put("X-Access-Token", Lists.newArrayList(token));
|
httpHeaders.put("X-Access-Token", Lists.newArrayList(token));
|
||||||
httpHeaders.put("Content-Type",Lists.newArrayList("application/json"));
|
httpHeaders.put("Content-Type",Lists.newArrayList("application/json"));
|
||||||
HttpEntity<String> httpEntity = new HttpEntity<>(json, httpHeaders);
|
HttpEntity<String> httpEntity = new HttpEntity<>(json, httpHeaders);
|
||||||
@ -202,15 +204,13 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
|
|||||||
/**
|
/**
|
||||||
* 生成接口访问令牌 Token
|
* 生成接口访问令牌 Token
|
||||||
*
|
*
|
||||||
* @param USERNAME
|
|
||||||
* @param PASSWORD
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getToken(String USERNAME, String PASSWORD) {
|
private String getToken(SysUser user) {
|
||||||
String token = JwtUtil.sign(USERNAME, PASSWORD);
|
// 使用封装方法:一步完成登录和设置用户信息
|
||||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
LoginUser loginUser = new LoginUser();
|
||||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 60);
|
BeanUtils.copyProperties(user, loginUser);
|
||||||
return token;
|
return LoginUserUtils.doLogin(loginUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.aliyuncs.exceptions.ClientException;
|
import com.aliyuncs.exceptions.ClientException;
|
||||||
@ -8,8 +9,9 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
import org.jeecg.common.util.LoginUserUtils;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CacheConstant;
|
import org.jeecg.common.constant.CacheConstant;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
@ -23,7 +25,6 @@ import org.jeecg.config.JeecgBaseConfig;
|
|||||||
import org.jeecg.modules.base.service.BaseCommonService;
|
import org.jeecg.modules.base.service.BaseCommonService;
|
||||||
import org.jeecg.modules.system.entity.SysDepart;
|
import org.jeecg.modules.system.entity.SysDepart;
|
||||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||||
import org.jeecg.modules.system.entity.SysTenant;
|
|
||||||
import org.jeecg.modules.system.entity.SysUser;
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
import org.jeecg.modules.system.model.SysLoginModel;
|
import org.jeecg.modules.system.model.SysLoginModel;
|
||||||
import org.jeecg.modules.system.service.*;
|
import org.jeecg.modules.system.service.*;
|
||||||
@ -31,7 +32,6 @@ import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
|||||||
import org.jeecg.modules.system.util.RandImageUtil;
|
import org.jeecg.modules.system.util.RandImageUtil;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.task.AsyncTaskExecutor;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -42,7 +42,6 @@ import java.util.*;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author scott
|
* @Author scott
|
||||||
@ -75,7 +74,7 @@ public class LoginController {
|
|||||||
/**
|
/**
|
||||||
* 线程池用于异步发送纪要
|
* 线程池用于异步发送纪要
|
||||||
*/
|
*/
|
||||||
public static ExecutorService cachedThreadPool = new ShiroThreadPoolExecutor(0, 1024, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
public static ExecutorService cachedThreadPool = new ThreadPoolExecutor(0, 1024, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||||
|
|
||||||
@Operation(summary="登录接口")
|
@Operation(summary="登录接口")
|
||||||
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
||||||
@ -149,7 +148,8 @@ public class LoginController {
|
|||||||
public Result<JSONObject> getUserInfo(HttpServletRequest request){
|
public Result<JSONObject> getUserInfo(HttpServletRequest request){
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Result<JSONObject> result = new Result<JSONObject>();
|
Result<JSONObject> result = new Result<JSONObject>();
|
||||||
String username = JwtUtil.getUserNameByToken(request);
|
// 使用Sa-Token获取登录用户名(loginId现在是username)
|
||||||
|
String username = StpUtil.getLoginIdAsString();
|
||||||
if(oConvertUtils.isNotEmpty(username)) {
|
if(oConvertUtils.isNotEmpty(username)) {
|
||||||
// 根据用户名查询用户信息
|
// 根据用户名查询用户信息
|
||||||
SysUser sysUser = sysUserService.getUserByName(username);
|
SysUser sysUser = sysUserService.getUserByName(username);
|
||||||
@ -200,7 +200,8 @@ public class LoginController {
|
|||||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||||
if(sysUser!=null) {
|
if(sysUser!=null) {
|
||||||
asyncClearLogoutCache(token, sysUser); // 异步清理
|
asyncClearLogoutCache(token, sysUser); // 异步清理
|
||||||
SecurityUtils.getSubject().logout();
|
// 使用Sa-Token退出登录
|
||||||
|
StpUtil.logout();
|
||||||
return Result.ok("退出登录成功!");
|
return Result.ok("退出登录成功!");
|
||||||
}else {
|
}else {
|
||||||
return Result.error("Token无效!");
|
return Result.error("Token无效!");
|
||||||
@ -208,17 +209,13 @@ public class LoginController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理用户缓存
|
* 清理用户缓存(使用Sa-Token)
|
||||||
*
|
*
|
||||||
* @param token
|
* @param token
|
||||||
* @param sysUser
|
* @param sysUser
|
||||||
*/
|
*/
|
||||||
private void asyncClearLogoutCache(String token, LoginUser sysUser) {
|
private void asyncClearLogoutCache(String token, LoginUser sysUser) {
|
||||||
cachedThreadPool.execute(()->{
|
cachedThreadPool.execute(()->{
|
||||||
//清空用户登录Token缓存
|
|
||||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
|
|
||||||
//清空用户登录Shiro权限缓存
|
|
||||||
redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
|
|
||||||
//清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
|
//清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
|
||||||
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
|
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
|
||||||
baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser);
|
baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser);
|
||||||
@ -290,7 +287,7 @@ public class LoginController {
|
|||||||
Result<JSONObject> result = new Result<JSONObject>();
|
Result<JSONObject> result = new Result<JSONObject>();
|
||||||
String username = user.getUsername();
|
String username = user.getUsername();
|
||||||
if(oConvertUtils.isEmpty(username)) {
|
if(oConvertUtils.isEmpty(username)) {
|
||||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
LoginUser sysUser = LoginUserUtils.getSessionUser();
|
||||||
username = sysUser.getUsername();
|
username = sysUser.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,15 +475,13 @@ public class LoginController {
|
|||||||
*/
|
*/
|
||||||
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request) {
|
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request) {
|
||||||
String username = sysUser.getUsername();
|
String username = sysUser.getUsername();
|
||||||
String syspassword = sysUser.getPassword();
|
|
||||||
// 获取用户部门信息
|
// 获取用户部门信息
|
||||||
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||||
|
|
||||||
//1.生成token
|
//1.使用sa-token生成token(使用username作为loginId,将用户信息存入session)
|
||||||
String token = JwtUtil.sign(username, syspassword);
|
LoginUser loginUser = new LoginUser();
|
||||||
// 设置token缓存有效时间
|
BeanUtils.copyProperties(sysUser, loginUser);
|
||||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
String token = LoginUserUtils.doLogin(loginUser);
|
||||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
|
||||||
obj.put("token", token);
|
obj.put("token", token);
|
||||||
|
|
||||||
//2.设置登录租户
|
//2.设置登录租户
|
||||||
@ -584,7 +579,7 @@ public class LoginController {
|
|||||||
/**
|
/**
|
||||||
* 切换菜单表为vue3的表
|
* 切换菜单表为vue3的表
|
||||||
*/
|
*/
|
||||||
@RequiresRoles({"admin"})
|
@SaCheckRole({"admin"})
|
||||||
@GetMapping(value = "/switchVue3Menu")
|
@GetMapping(value = "/switchVue3Menu")
|
||||||
public Result<String> switchVue3Menu(HttpServletResponse response) {
|
public Result<String> switchVue3Menu(HttpServletResponse response) {
|
||||||
Result<String> res = new Result<String>();
|
Result<String> res = new Result<String>();
|
||||||
@ -656,11 +651,11 @@ public class LoginController {
|
|||||||
//5. 设置登录用户信息
|
//5. 设置登录用户信息
|
||||||
obj.put("userInfo", sysUser);
|
obj.put("userInfo", sysUser);
|
||||||
|
|
||||||
//6. 生成token
|
//6. 使用Sa-Token生成token(使用username作为loginId、将用户信息存入session)
|
||||||
String token = JwtUtil.sign(username, syspassword);
|
LoginUser loginUser = new LoginUser();
|
||||||
// 设置超时时间
|
BeanUtils.copyProperties(sysUser, loginUser);
|
||||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
String token = LoginUserUtils.doLogin(loginUser);
|
||||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
log.info("App登录成功,用户名:{},token={}", username, token);
|
||||||
|
|
||||||
//token 信息
|
//token 信息
|
||||||
obj.put("token", token);
|
obj.put("token", token);
|
||||||
@ -792,7 +787,7 @@ public class LoginController {
|
|||||||
result.setSuccess(false);
|
result.setSuccess(false);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
LoginUser sysUser = LoginUserUtils.getSessionUser();
|
||||||
String username = sysUser.getUsername();
|
String username = sysUser.getUsername();
|
||||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||||
query.eq(SysUser::getUsername, username).eq(SysUser::getPhone, mobile);
|
query.eq(SysUser::getUsername, username).eq(SysUser::getPhone, mobile);
|
||||||
|
|||||||
@ -1,28 +1,23 @@
|
|||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.session.SaSession;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CacheConstant;
|
import org.jeecg.common.constant.CacheConstant;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.util.RedisUtil;
|
import org.jeecg.common.util.RedisUtil;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.base.service.BaseCommonService;
|
import org.jeecg.modules.base.service.BaseCommonService;
|
||||||
import org.jeecg.modules.system.service.ISysUserService;
|
|
||||||
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
|
||||||
import org.jeecg.modules.system.vo.SysUserOnlineVO;
|
import org.jeecg.modules.system.vo.SysUserOnlineVO;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -39,43 +34,58 @@ public class SysUserOnlineController {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
@Autowired
|
|
||||||
public RedisTemplate redisTemplate;
|
|
||||||
@Autowired
|
|
||||||
public ISysUserService userService;
|
|
||||||
@Autowired
|
|
||||||
private SysBaseApiImpl sysBaseApi;
|
|
||||||
@Resource
|
@Resource
|
||||||
private BaseCommonService baseCommonService;
|
private BaseCommonService baseCommonService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取在线用户列表(使用Sa-Token)
|
||||||
|
*/
|
||||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||||
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username,
|
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username,
|
||||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||||
Collection<String> keys = redisUtil.scan(CommonConstant.PREFIX_USER_TOKEN + "*");
|
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||||
List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
|
List<SysUserOnlineVO> onlineList = new ArrayList<>();
|
||||||
for (String key : keys) {
|
|
||||||
String token = (String)redisUtil.get(key);
|
try {
|
||||||
if (StringUtils.isNotEmpty(token)) {
|
// 使用Sa-Token获取所有在线用户的session ID列表
|
||||||
SysUserOnlineVO online = new SysUserOnlineVO();
|
List<String> sessionIdList = StpUtil.searchSessionId("", 0, -1, false);
|
||||||
online.setToken(token);
|
|
||||||
//TODO 改成一次性查询
|
for (String sessionId : sessionIdList) {
|
||||||
LoginUser loginUser = sysBaseApi.getUserByName(JwtUtil.getUsername(token));
|
try {
|
||||||
if (loginUser != null && !"_reserve_user_external".equals(loginUser.getUsername())) {
|
// 获取session
|
||||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
SaSession session = StpUtil.getSessionBySessionId(sessionId);
|
||||||
//验证用户名是否与传过来的用户名相同
|
if (session == null) {
|
||||||
boolean isMatchUsername=true;
|
continue;
|
||||||
//判断用户名是否为空,并且当前循环的用户不包含传过来的用户名,那么就设成false
|
|
||||||
if(oConvertUtils.isNotEmpty(username) && !loginUser.getUsername().contains(username)){
|
|
||||||
isMatchUsername = false;
|
|
||||||
}
|
}
|
||||||
if(isMatchUsername){
|
|
||||||
BeanUtils.copyProperties(loginUser, online);
|
// 从session中获取用户信息
|
||||||
onlineList.add(online);
|
LoginUser loginUser = (LoginUser) session.get("loginUser");
|
||||||
|
if (loginUser != null && !"_reserve_user_external".equals(loginUser.getUsername())) {
|
||||||
|
// 用户名筛选
|
||||||
|
if (oConvertUtils.isEmpty(username) || loginUser.getUsername().contains(username)) {
|
||||||
|
SysUserOnlineVO online = new SysUserOnlineVO();
|
||||||
|
BeanUtils.copyProperties(loginUser, online);
|
||||||
|
|
||||||
|
// 获取该用户的token(loginId现在是username)
|
||||||
|
try {
|
||||||
|
String token = StpUtil.getTokenValueByLoginId(loginUser.getUsername());
|
||||||
|
online.setToken(token);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("获取用户token失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
onlineList.add(online);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
} catch (Exception e) {
|
||||||
|
// 旧的Session数据可能导致反序列化失败,记录debug级别日志即可
|
||||||
|
log.debug("获取session失败(可能是旧数据): {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取在线用户列表失败: {}", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.reverse(onlineList);
|
Collections.reverse(onlineList);
|
||||||
|
|
||||||
Page<SysUserOnlineVO> page = new Page<SysUserOnlineVO>(pageNo, pageSize);
|
Page<SysUserOnlineVO> page = new Page<SysUserOnlineVO>(pageNo, pageSize);
|
||||||
@ -100,30 +110,33 @@ public class SysUserOnlineController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 强退用户
|
* 强退用户(使用Sa-Token)
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/forceLogout",method = RequestMethod.POST)
|
@RequestMapping(value = "/forceLogout",method = RequestMethod.POST)
|
||||||
public Result<Object> forceLogout(@RequestBody SysUserOnlineVO online) {
|
public Result<Object> forceLogout(@RequestBody SysUserOnlineVO online) {
|
||||||
//用户退出逻辑
|
try {
|
||||||
if(oConvertUtils.isEmpty(online.getToken())) {
|
// 验证参数
|
||||||
return Result.error("退出登录失败!");
|
if (oConvertUtils.isEmpty(online.getToken())) {
|
||||||
}
|
return Result.error("Token不能为空!");
|
||||||
String username = JwtUtil.getUsername(online.getToken());
|
}
|
||||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
|
||||||
if(sysUser!=null) {
|
// 使用Sa-Token通过token强制退出登录
|
||||||
baseCommonService.addLog("强制: "+sysUser.getRealname()+"退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser);
|
StpUtil.logoutByTokenValue(online.getToken());
|
||||||
log.info(" 强制 "+sysUser.getRealname()+"退出成功! ");
|
|
||||||
//清空用户登录Token缓存
|
// 清空用户的缓存信息(如果有用户名)
|
||||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + online.getToken());
|
if (oConvertUtils.isNotEmpty(online.getUsername())) {
|
||||||
//清空用户登录Shiro权限缓存
|
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, online.getUsername()));
|
||||||
redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
|
}
|
||||||
//清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
|
|
||||||
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
|
// 记录日志
|
||||||
//调用shiro的logout
|
String username = oConvertUtils.isNotEmpty(online.getUsername()) ? online.getUsername() : "未知用户";
|
||||||
SecurityUtils.getSubject().logout();
|
baseCommonService.addLog("强制: " + username + " 退出成功!", CommonConstant.LOG_TYPE_1, null);
|
||||||
|
log.info("强制 {} 退出成功!", username);
|
||||||
|
|
||||||
return Result.ok("退出登录成功!");
|
return Result.ok("退出登录成功!");
|
||||||
}else {
|
} catch (Exception e) {
|
||||||
return Result.error("Token无效!");
|
log.error("强制退出失败: {}", e.getMessage(), e);
|
||||||
|
return Result.error("退出登录失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,9 @@ import org.jeecg.common.constant.CommonConstant;
|
|||||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
import org.jeecg.common.system.util.JwtUtil;
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.common.util.*;
|
import org.jeecg.common.util.*;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.jeecg.modules.base.service.BaseCommonService;
|
import org.jeecg.modules.base.service.BaseCommonService;
|
||||||
import org.jeecg.modules.system.entity.SysDepart;
|
import org.jeecg.modules.system.entity.SysDepart;
|
||||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||||
@ -211,12 +213,10 @@ public class ThirdLoginController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String saveToken(SysUser user) {
|
private String saveToken(SysUser user) {
|
||||||
// 生成token
|
// 使用封装方法:一步完成登录和设置用户信息
|
||||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
|
LoginUser loginUser = new LoginUser();
|
||||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
BeanUtils.copyProperties(user, loginUser);
|
||||||
// 设置超时时间
|
return LoginUserUtils.doLogin(loginUser);
|
||||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user