admin 管理员组文章数量: 1086019
若依分离版解决单个账号多设备登录问题
1.application.yml
添加相关配置,用于灵活控制单个账号多设备登录的情况
#token配置
token: # 这个是若依框架本身存在的配置
# 是否允许并多设备登录 true:允许 false:不允许 这个是新增的配置
singleLogin: false
2.CacheConstants
类中新增常量
/**
* 登录用户id redis key 用于实现灵活控制多设备登录
*/
public static final String LOGIN_USER_ID_KEY = "login_user_ids:";
3.TokenService
类中新增相关代码(重要改动)
头部添加获取我们上面新增的配置
// 是否允许多设备登录
@Value("${token.singleLogin}")
private boolean singleLogin;
在尾部添加涉及本次控制并发登录所需要的redis key组成
//userId 是 当前登录用户的主键id 注意:若依分离版默认的用户主键是Integer类型,博主实际项目后续做过调整,已改成String类型
private String getUserKey(String userId)
{
return CacheConstants.LOGIN_USER_ID_KEY + userId;
}
在refreshToken
方法中做代码调整
主要原因:在这里做主要是保证后续如果由多种登录方式 手机验证码等 可以兼容(只要都调用了createToken
方法去创建token令牌)
源代码:
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
改造后:
//如果不允许多设备登录,则获取之前的token以及userId 判断存在,则删除
if(!singleLogin){//多设备登录限制相关代码
String userIdKey = getUserKey(loginUser.getUserId());
String userKey = redisCache.getCacheObject(userIdKey);
if(StringUtils.isNotEmpty(userKey)){
redisCache.deleteObject(userIdKey);
redisCache.deleteObject(userKey);
}
}
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
if(!singleLogin){//多设备登录限制相关代码
String userIdKey = getUserKey(loginUser.getUserId());
redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
}
对delLoginUser
做代码新增,这个方法用于手动退出时 删除对应的token以及我们本次维护的redis key,也就是后续对LogoutSuccessHandlerImpl
类做调整的一部分
源代码:
public void delLoginUser(String token)
{
if (StringUtils.isNotEmpty(token))
{
String userKey = getTokenKey(token);
redisCache.deleteObject(userKey);
}
}
改造后:
public void delLoginUser(String token,String userId)
{
if (StringUtils.isNotEmpty(token))
{
String userKey = getTokenKey(token);
redisCache.deleteObject(userKey);
}
if (StringUtils.isNotEmpty(userId))
{
String userIdKey = getUserKey(userId);
redisCache.deleteObject(userIdKey);
}
}
新增用于强制推出方法,用于后续SysUserOnlineController
类强制退出接口代码做相关调整,在前端的监控-在线用户界面做强退操作
/**
* 强制退出
* @param tokenId token(uuid)
*/
public void forceLogout(String tokenId){
String userKey = getTokenKey(tokenId);
if(!singleLogin){//多设备登录相关控制代码
LoginUser loginUser = redisCache.getCacheObject(userKey);
String userId = loginUser.getUserId();
String userIdKey = getUserKey(userId);
redisCache.deleteObject(userIdKey);
}
redisCache.deleteObject(userKey);
}
4.自定义退出处理类LogoutSuccessHandlerImpl
做调整
源代码:
tokenService.delLoginUser(loginUser.getToken());
改造后:
tokenService.delLoginUser(loginUser.getToken(),loginUser.getUserId());
5.在线用户监控接口类SysUserOnlineController
做相关调整
头部引入TokenService
类,注意引包时,引入项目的,而不是Security包的
import com.ruoyi.framework.web.service.TokenService;
@Autowired
private TokenService tokenService;
强退方法forceLogout
调整
源代码:
public AjaxResult forceLogout(@PathVariable String tokenId)
{
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
return AjaxResult.success();
}
改造后:
tokenService.forceLogout(tokenId);
参考:
若依项目如何实现一个账户只能一个人登录(汇总)
版权声明:本文标题:若依分离版解决单个账号多设备登录问题 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1738290962a1957919.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论