使用Redis实现单用户登录功能

01.项目场景:

简述项目相关背景:
系统需要能够通过数据字典的开关来实现单用户登录


02.问题描述

描述项目中遇到的问题:
一开始的思路是在用户第一次登录发起请求时,通过key来获取token,与请求头中的token对比,若相同则说明没有第二次登录,若不同则说明有第二次登录,第一次登录的就需要下线
但是发现redis中保存token的key是前缀+token的形式,因此就没办法拿到key


03.解决方案:

该问题的具体解决方案:

因为单用户登录时,它的username是相同的,所以整体思路就是遍历redis中的token,然后根据token获取username,将之与正在登录的用户的username做对比 若相同再加上对数据字典的单用户登录是否启用的判断,来执行后面的操作

		Result<JSONObject> result = new Result<JSONObject>();
		//根据前缀tokenFlag查询出redis中token
		Set<String> keys = redisTemplate.keys(CommonConstant.TOKEN_FLAG+ "*");
		String redisToken;
		String redisUsername;
		//查询系统字典中的loginRestrict的字典项
		SysDict sysDict = sysDictService.getOne(new LambdaQueryWrapper<SysDict>()
				.eq(SysDict::getDictCode,CommonConstant.LOGIN));
		//多端登录后者挤掉前者
		String afterCanStatus = null;
		//多端登录后者不可登录
		String afterNotStatus = null;
		if (ObjectUtil.isNotNull(sysDict)) {
			//通过字典编码查询字典项纪录集合
			List<SysDictItem> sysDictItemList = sysDictItemService.getItemsByDictCode(sysDict.getDictCode());
			for (SysDictItem sysDictItem : sysDictItemList) {
				if (CommonConstant.LOGIN_RESTRICT_001.equals(sysDictItem.getItemValue())) {
					//后者挤掉前者标识
					afterCanStatus = sysDictItem.getStatus();
				} else {
					//后者不能登录标识
					afterNotStatus = sysDictItem.getStatus();
				}
			}
			//遍历key取username
			for (String key : keys) {
				redisToken = key.substring(18);
				//取redis中的username
				redisUsername = JwtUtil.getUsername(redisToken);
				//与当前登录用户的username作比对,有相同的并且数据字典为后者强制前者下线则把redis中的key删除
				if (username.equals(redisUsername) && CommonConstant.STATUS_1.equals(afterCanStatus)) {
					redisTemplate.delete(key);
				} else if (username.equals(redisUsername) && CommonConstant.STATUS_1.equals(afterNotStatus)) {
				//与当前登录用户的username作比对,有相同的并且数据字典为后者不可登录则把redis中的key删除
					result.error500("该账户已登录,不可重复登录");
					return result;
				}
			}
		}
		return result;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值