jwt用户登录 实现用户同时在线数量限制

5 篇文章 0 订阅

通常系统都会限制同一个账号的登录人数,多人登录要么限制后者登录,要么踢出前者,今天讲的是踢出前者。

JWT(token)存储在Redis中,类似 JSessionId-Session的关系,用户登录后每次请求在Header中携带jwt

比较时间戳

维护一个 username: jwtToken 这样的一个 key-value 在Reids中

 

拦截器逻辑

package com.gitee.taven.filter;

import com.gitee.taven.utils.JWTUtil;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 比较时间戳
 */
public class CompareKickOutFilter extends KickOutFilter {
    @Override
    public boolean isAccessAllowed(HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader("Authorization");
        String username = JWTUtil.getUsername(token);
        String userKey = PREFIX + username;

        RBucket<String> bucket = redissonClient.getBucket(userKey);
        String redisToken = bucket.get();

        if (token.equals(redisToken)) {
            return true;

        } else if (StringUtils.isBlank(redisToken)) {
            bucket.set(token);

        } else {
            Long redisTokenUnixTime = JWTUtil.getClaim(redisToken, "createTime").asLong();
            Long tokenUnixTime = JWTUtil.getClaim(token, "createTime").asLong();

            // token > redisToken 则覆盖
            if (tokenUnixTime.compareTo(redisTokenUnixTime) > 0) {
                bucket.set(token);

            } else {
                // 注销当前token
                userService.logout(token);
                sendJsonResponse(response, 4001, "您的账号已在其他设备登录");
                return false;

            }

        }

        return true;

    }
}

 

用户登录成功 生成token给到用户 同时存储到redis中(key值为用户名(标识)) 

用户再次访问系统请求参数中带有token信息 后台拦截进行比对

如果token匹配成功 就放行 匹配不成功 说明两个token不一致 开始比对对应的时间戳 后者时间戳 大于前者 就把当前token覆盖(如果旧的token请求再次进来 期时间戳就晚于当前redis中的token时间(token已经更新)判断其为被踢出的用户提示重新登录)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值