RuoYi-Cloud版本限制一个账户只能在一个地方登陆
业务需求:同一个账户只能在一个地方登陆,后登录的账号挤掉之前登陆的账号思路就是:修改redis登录的key,目前的key只存放了token,修改为userid(id为唯一) + key的方式去判断,登录前判断redis中当前登录用户是否已经登录,如果已经登录删除已经存在的token和userId。
·
RuoYi-Cloud版本限制一个账户只能在一个地方登陆
- 一. 前言
- 二. 参考
- 三. 代码实现
- 三.一 在ruoyi-auth模块下的bootstrap.yml文件下新增一个配置soloLogin用于限制多终端同时登录。
- 三.二 我是在CacheConstants.java下添加用户缓存的常量
- 三.三 修改 TokenService.java类下的方法
- 三.四 修改登录方法SysLoginService.java,验证如果用户不允许多终端同时登录,清除缓存信息
- 三.五 修改AuthLogic.java中会话注销方法
- 四. 总结
一. 前言
目前框架用的是RuoYi-Cloud版本:https://github.com/yangzongzhuan/RuoYi-Cloud
业务需求:同一个账户只能在一个地方登陆,后登录的账号挤掉之前登陆的账号
二. 参考
参考了若依分离版,后面有改动 如何限制账户不允许多终端登录 https://doc.ruoyi.vip/ruoyi-vue/other/faq.html#%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E8%B4%A6%E6%88%B7%E4%B8%8D%E5%85%81%E8%AE%B8%E5%A4%9A%E7%BB%88%E7%AB%AF%E7%99%BB%E5%BD%95
三. 代码实现
三.一 在ruoyi-auth模块下的bootstrap.yml文件下新增一个配置soloLogin用于限制多终端同时登录。
# token配置
token:
# 是否允许账户多终端同时登录(true允许 false不允许)
soloLogin: false
如图:
在ruoyi-system模块下的bootstrap.yml也同样加上
三.二 我是在CacheConstants.java下添加用户缓存的常量
/**
* 登录用户编号 redis key
*/
public static final String LOGIN_USERID_KEY = "login_userid:";
三.三 修改 TokenService.java类下的方法
/**
* 是否允许账户多终端同时登录(true允许 false不允许)
*/
@Value("${token.soloLogin}")
private boolean soloLogin;
修改方法:
/**
* 删除用户缓存信息
*/
public void delLoginUser(String token, Long userId) {
if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token);
redisService.deleteObject(getTokenKey(userkey));
}
if (!soloLogin && StringUtils.isNotNull(userId)) {
String userIdKey = getUserIdKey(userId);
redisService.deleteObject(userIdKey);
}
}
/**
* 刷新令牌有效期
*
* @param loginUser 登录信息
*/
public void refreshToken(LoginUser loginUser) {
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
if (!soloLogin)
{
// 缓存用户唯一标识,防止同一帐号,同时登录
String userIdKey = getUserIdKey(loginUser.getSysUser().getUserId());
redisService.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
}
}
private String getTokenKey(String token) {
return ACCESS_TOKEN + token;
}
private String getUserIdKey(Long userId)
{
return CacheConstants.LOGIN_USERID_KEY + userId;
}
三.四 修改登录方法SysLoginService.java,验证如果用户不允许多终端同时登录,清除缓存信息
/**
* 是否允许账户多终端同时登录(true允许 false不允许)
*/
@Value("${token.soloLogin}")
private boolean soloLogin;
/**
* 登录
*/
public LoginUser login(String username, String password)
{
==================前面的代码============
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
==================我在这里加判断的 新增的代码============
if (!soloLogin)
{
// 如果用户不允许多终端同时登录,清除缓存信息
String userIdKey = CacheConstants.LOGIN_USERID_KEY + user.getUserId();
String userKey = redisService.getCacheObject(userIdKey);
if (StringUtils.isNotEmpty(userKey))
{
redisService.deleteObject(userIdKey);
redisService.deleteObject(userKey);
}
}
===============后面的代码===========
return userInfo;
}
三.五 修改AuthLogic.java中会话注销方法
/**
* 会话注销,根据指定Token
*/
public void logoutByToken(String token)
{
LoginUser loginUser = getLoginUser(token);
if(loginUser!=null){
tokenService.delLoginUser(token,loginUser.getUserid());
}else{
tokenService.delLoginUser(token,null);
}
}
这里是用户注销的时候调用的。
四. 总结
思路就是:修改redis登录的key,目前的key只存放了token,修改为userid(id为唯一) + key的方式去判断,登录前判断redis中当前登录用户是否已经登录,如果已经登录删除已经存在的token和userId。
更多推荐
已为社区贡献1条内容
所有评论(0)