基于redis实现 jwt 单设备登陆

最近在研究security单设备登陆,单体的security(不使用oauth2)可以用内置的session设置session最大数量来实现单设备。oauth2的jwt该如何来实现单设备登陆?

参考了几篇文章,是继承DefaultTokenServices或者实现TokenService,但是好麻烦,最重要的是,,我没看懂。。。不知道该实现哪个类

但是。。代码还是得实现的,条条道路通罗马,不一定非得重写

先说一下我的项目的oauth流程

用户user/管理员admin通过/user/login/admin/login的controller来进入业务层,业务层通过restTemplate调用自身的/login/token,传入用户或管理员的client_id及对应的secret,来分离前后端登陆,上图

到UserDetailsService的实现类时,通过SecurityContextHolder中传入的client_id的值来判断调用哪个feign来查询

当security内部校验通过后,生成jwt后,把jwt的jti作为key,jwt作为value存储到redis,jti给客户

当客户携带着jti访问资源服务器时,先经过gateway进行请求的增强,Authorization为消息头,值时Bearer+空格+jwt(jwt通过jti从redis中取出,redis没用这个值,要么没登陆,要么过期,返回401/302跳转),放行至下游资源服务器

捋了捋流程,单设备的实现方法好像也有思路了

我想了个思路,jtw再创建后,返回给客户之前,先用一个特定的字符串+id(id是雪花算法生成的id,不存在重复的问题)拼成一个key(后面都简称key了),value是jti,以key-value的形式存到redis中。下一次登陆时,先判断这个key再redis中是否存在,(顶号登陆,后登录的,踢下前一台设备)存在则删除key-jti组合和jti-jwt组合,不存在说明没有设备登陆

上图

测试一下:

第一次登陆

postman再次登陆:

redis中依旧只有两条数据,原有的两条数据已经被删除,完美实现顶号登陆!

禁止第二台设备登陆,现在只有思路,但是还未实现

登陆时需要把ip+设备号或其他一些证明身份的信息生成一个md5,来标志一个设备,如果同一账号且同一设备登陆,把第一个登陆删掉就行(可能是用户直接关掉了浏览器而未注销登陆),但是如果同一账号不同设备,则禁止该设备登陆(同一账号多地登陆的情况)

因代码太多,只展示了部分代码截图,项目完成之后会推送到jitee上


版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44352617/article/details/117641055