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 限制内存使用大小的实现
May 08 Redis
详解Redis主从复制实践
May 19 Redis
Windows下redis下载、redis安装及使用教程
Jun 02 Redis
解析Redis Cluster原理
Jun 21 Redis
在redisCluster中模糊获取key方式
Jul 09 Redis
Redis Cluster 集群搭建你会吗
Aug 04 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
Redis中有序集合的内部实现方式的详细介绍
Mar 16 Redis
使用Redis实现点赞取消点赞的详细代码
Mar 20 Redis
Redis 哨兵机制及配置实现
Mar 25 Redis
Redis基本数据类型哈希Hash常用操作命令
Jun 01 Redis
Redis Lua脚本实现ip限流示例
Jul 15 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
在php中使用sockets:从新闻组中获取文章
2006/10/09 PHP
JavaScript获取GridView选择的行内容
2009/04/14 Javascript
JS小功能(button选择颜色)简单实例
2013/11/29 Javascript
Node.js中require的工作原理浅析
2014/06/24 Javascript
初识Node.js
2014/09/03 Javascript
JS实现自定义简单网页软键盘效果代码
2015/11/05 Javascript
每日十条JavaScript经验技巧(一)
2016/06/23 Javascript
详解js界面跳转与值传递
2016/11/22 Javascript
图解Javascript——作用域、作用域链、闭包
2017/03/21 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
微信小程序自定义底部导航带跳转功能
2018/11/27 Javascript
JavaScript键盘事件常见用法实例分析
2019/01/03 Javascript
微信小程序实现分享朋友圈的图片功能示例
2019/01/18 Javascript
深入解析vue 源码目录及构建过程分析
2019/04/24 Javascript
vue elementUI table 自定义表头和行合并的实例代码
2019/05/22 Javascript
Vue export import 导入导出的多种方式与区别介绍
2020/02/12 Javascript
JavaScript如何使用插值实现图像渐变
2020/06/28 Javascript
vue3.0 加载json的方法(非ajax)
2020/10/26 Javascript
[02:41]DOTA2英雄基础教程 亚巴顿
2014/01/02 DOTA
[01:32]DOTA2上海特锦赛现场采访:最想COS的英雄
2016/03/25 DOTA
Python实现批量下载文件
2015/05/17 Python
Python利用正则表达式匹配并截取指定子串及去重的方法
2015/07/30 Python
Flask模拟实现CSRF攻击的方法
2018/07/24 Python
Python XML转Json之XML2Dict的使用方法
2019/01/15 Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
2019/10/24 Python
python求一个字符串的所有排列的实现方法
2020/02/04 Python
html5 CSS过度-webkit-transition使用介绍
2013/07/02 HTML / CSS
多视角3D可旋转的HTML5 Logo动画
2016/03/02 HTML / CSS
美国糖果店:Sugarfina
2019/02/21 全球购物
承诺书模板
2014/08/30 职场文书
领导四风问题整改措施思想汇报
2014/10/13 职场文书
农民工工资承诺书大全
2015/05/04 职场文书
2015年人民调解工作总结
2015/05/18 职场文书
护士岗位竞聘书
2015/09/15 职场文书
PYTHON使用Matplotlib去实现各种条形图的绘制
2022/03/22 Python
排查MySQL生产环境索引没有效果
2022/04/11 MySQL