RuoYi框架 限制账户不允许多终端登录

RuoYi框架 限制账户不允许多终端登录

一、需求

  • 在管理系统中,一般情况一个账号是可以多客户端进行登录。但是这样可能造成安全隐患,当同一账号的多端同时操作同一业务时,有可能造成数据混肴的后果。那么就需要同一时间一个账号只能一个地方登录。另一端登录,则原先登录的客户端则会失效。

二、解决原理

  • 登录后获取的用户ID和token存入redis中,以用户ID为key,token为value的格式存入。注销时,则从redis中删除。当第二个人登录时,如果发现redis中已经存在该用户对应的key,则说明该账号已经登录,则将登录生成的token覆盖原token,从而使之前登录的客户端失效。限制账户不允许多终端登录。

三、实例代码

RuoYi官网实例

  • 1.application.yml新增一个配置soloLogin用于限制是否启用多终端同时登录。
token:
    # 是否允许账户多终端同时登录(true允许 false不允许)
    soloLogin: false
  • 2.Constants.java(已存在的JAVA类)新增一个常量LOGIN_USERID_KEY公用。
/**
 * 登录用户编号 redis key
 * 加上独特的前缀,避免重复的key
 */
public static final String LOGIN_USERID_KEY = "login_userid:";
  • 3.调整TokenService.java(已存在的JAVA类),存储&刷新缓存用户编号信息
// 是否允许账户多终端同时登录(true允许 false不允许)
@Value("${token.soloLogin}")
private boolean soloLogin;

/**
 * 删除用户身份信息
 * 可以在原基础上修改,也可以作为重载方法新增该方法
 */
public void delLoginUser(String token, Long userId){
	if (StringUtils.isNotEmpty(token)){
		String userKey = getTokenKey(token);
		redisCache.deleteObject(userKey);
	}
	/* 添加的部分
	* 删除身份信息的同时,将redis中的缓存同时删除
	*/
	if (!soloLogin && StringUtils.isNotNull(userId)){
		String userIdKey = getUserIdKey(userId);
		redisCache.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());
	redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
	// 是否限制多端登录
	if (!soloLogin){
		// 缓存用户唯一标识,防止同一帐号,同时登录
		String userIdKey = getUserIdKey(loginUser.getUser().getUserId());
		// 刷新缓存中的token
		redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
	}
}
// 处理key,userId添加前缀,避免key重复
private String getUserIdKey(Long userId){
	return Constants.LOGIN_USERID_KEY + userId;
}
  • 4.自定义退出处理类LogoutSuccessHandlerImpl.java(登出函数所在的类)清除缓存方法添加用户编号
/*
* 删除用户缓存记录
* 登出会话的方法中,删除redis缓存
*/
public void logout(){
	tokenService.delLoginUser(loginUser.getToken(), loginUser.getUser().getUserId());
}
  • 5.登录方法SysLoginService.java(已存在的JAVA类),验证如果用户不允许多终端同时登录,清除缓存信息
// 是否允许账户多终端同时登录(true允许 false不允许)
@Value("${token.soloLogin}")
private boolean soloLogin;
public LoginUser login(String username, String password){
	// 原代码块
	......

	if (!soloLogin){
		// 如果用户不允许多终端同时登录,清除缓存信息
		String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId();
		String userKey = redisCache.getCacheObject(userIdKey);
		if (StringUtils.isNotEmpty(userKey)){
			redisCache.deleteObject(userIdKey);
			redisCache.deleteObject(userKey);
		}
	}
}	

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值