Redis实现一个账号只能登录一个设备


Posted in Redis onApril 19, 2022

在有些场景下,我们希望用户一个账号只能登录一个设备。

这个时候我们可以用Redis来实现。

原理: 用户首次登录时,将用户信息存入Redis,key是用户id,value是token。当用户在其他设备登录时,会重新生成token,这个时候原先的token已经被覆盖了。所以用户在访问需要登录账号的操作时,系统会拦截请求判断token是否存在。当然是不存在的,所以我们就实现了单个设备登录的需求。

这里只提供大概的样例。

用户登录

@PostMapping("login")
@ApiOperation(value = "用户登录",notes = "用户登录")
public GraceJSONResult login(@RequestParam String userId,HttpServletRequest request) throws Exception {
    String uToken = UUID.randomUUID().toString();
    //把token存入redis
    redis.set("redis_user_token"+":"+userId,uToken);
    //返回用户信息,包含token
    return GraceJSONResult.ok(usersVO);
}

拦截器

拦截哪些操作需要用户登录,在拦截器中实现单设备登录。

说明:BaseInfoProperties是共有的代码,集成这个类就可以直接使用reidis。

public class BaseInfoProperties {
    @Autowired
    public RedisOperator redis;
}

说明:GraceException是自定义的抛出异常的类,这里不做展示。

public class UserTokenInterceptor extends BaseInfoProperties implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userId = request.getHeader("headerUserId");
        String userToken = request.getHeader("headerUserToken");
        // 判断用户id和token是否为空
        if(StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)){
            String redisToken=redis.get(REDIS_USER_TOKEN+":"+userId);
            //判断token是否失效
            if(StringUtils.isBlank(redisToken)){
                GraceException.display(ResponseStatusEnum.UN_LOGIN);
                return false;
            }else {
                //判断token是否一致,如果不一致,表示用户在别的手机端登录,token被覆盖了
                if(!redisToken.equalsIgnoreCase(redisToken)){
                    GraceException.display(ResponseStatusEnum.TICKET_INVALID);
                    return false;
                }
            }
        }else {
            // 用户id和token为空
            GraceException.display(ResponseStatusEnum.UN_LOGIN);
            return false;
        }

        return true;
    }
}

注册拦截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer{
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //要拦截的请求,哪些需要登录
        registry.addInterceptor(userTokenInterceptor())
                .addPathPatterns("/userInfo/modifyUserInfo")
                .addPathPatterns("/userInfo/modifyImage");
    }
    //用户未登录拦截器
    @Bean
    public UserTokenInterceptor userTokenInterceptor() {
       return  new UserTokenInterceptor();
    }
}

到此这篇关于Redis实现单设备登录的文章就介绍到这了!

Redis 相关文章推荐
浅谈Redis在直播场景的实践方案
Apr 27 Redis
在K8s上部署Redis集群的方法步骤
Apr 27 Redis
使用Redis实现秒杀功能的简单方法
May 08 Redis
基于Redis过期事件实现订单超时取消
May 08 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
Redis源码阅读:Redis字符串SDS详解
Jul 15 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
详解Redis在SpringBoot工程中的综合应用
Oct 16 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
解决redis批量删除key值的问题
Mar 23 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
虫族 Zerg 历史背景
2020/03/14 星际争霸
PHPLog php 程序调试追踪工具
2009/09/09 PHP
php的XML文件解释类应用实例
2014/09/22 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
张孝祥JavaScript学习阶段性总结(2)--(X)HTML学习
2007/02/03 Javascript
在JavaScript中使用inline函数的问题
2007/03/08 Javascript
javascript getElementsByTagName
2011/01/31 Javascript
js判断一个元素是否为另一个元素的子元素的代码
2012/03/21 Javascript
对Web开发中前端框架与前端类库的一些思考
2015/03/27 Javascript
jQuery实现在下拉列表选择时获取json数据的方法
2015/04/16 Javascript
jQuery无刷新分页完整实例代码
2015/10/27 Javascript
ajax在兼容模式下失效的快速解决方法
2016/03/22 Javascript
js实现增加数字显示的环形进度条效果
2017/02/05 Javascript
js 调用百度分享功能
2017/02/27 Javascript
vue的无缝滚动组件vue-seamless-scroll实例
2017/12/18 Javascript
nodejs微信开发之接入指南
2019/03/17 NodeJs
微信小程序批量监听输入框对按钮样式进行控制的实现代码
2019/10/12 Javascript
jQuery实现颜色打字机的完整代码
2020/03/19 jQuery
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
2016/04/13 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
2019/01/08 Python
django 实现编写控制登录和访问权限控制的中间件方法
2019/01/15 Python
Pytorch之contiguous的用法
2019/12/31 Python
pytorch中图像的数据格式实例
2020/02/11 Python
django 实现简单的插入视频
2020/04/07 Python
python ETL工具 pyetl
2020/06/07 Python
Python json格式化打印实现过程解析
2020/07/21 Python
django前端页面下拉选择框默认值设置方式
2020/08/09 Python
西班牙多品牌鞋店连锁店:Krack
2018/11/30 全球购物
口头翻译求职人自荐信
2013/12/07 职场文书
工作中个人的自我评价
2013/12/31 职场文书
校园报刊亭的创业计划书
2014/01/02 职场文书
护林员个人总结
2015/03/04 职场文书
2015年车间管理工作总结
2015/07/23 职场文书
2016大一新生军训心得体会
2016/01/11 职场文书
CSS变量实现主题切换的方法
2021/06/23 HTML / CSS
SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法
2022/07/07 Java/Android