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 24 Redis
为Java项目添加Redis缓存的方法
May 18 Redis
redis实现共同好友的思路详解
May 26 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
Redis中一个String类型引发的惨案
Jul 25 Redis
在项目中使用redis做缓存的一些思路
Sep 14 Redis
解决Redis启动警告问题
Feb 24 Redis
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列的问题
Mar 16 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
Apr 07 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
利用Redis实现点赞功能的示例代码
Jun 28 Redis
redis lua限流算法实现示例
Jul 15 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
使用 laravel sms 构建短信验证码发送校验功能
2017/11/06 PHP
PDO::errorInfo讲解
2019/01/28 PHP
用Laravel轻松处理千万级数据的方法实现
2020/12/25 PHP
javaScript call 函数的用法说明
2010/04/09 Javascript
JavaScript 构造函数 面相对象学习必备知识
2010/06/09 Javascript
javascript简单判断输入内容是否合法的方法
2016/05/11 Javascript
浅谈JavaScript中数组的增删改查
2016/06/20 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
2016/10/26 Javascript
jsTree事件和交互以及插件plugins详解
2017/08/29 Javascript
node.js到底要不要加分号浅析
2018/07/11 Javascript
Vue 配合eiement动态路由,权限验证的方法
2018/09/26 Javascript
详解VUE项目中安装和使用vant组件
2019/04/28 Javascript
vue制作toast组件npm包示例代码
2020/10/29 Javascript
python字典get()方法用法分析
2015/04/17 Python
用Python操作字符串之rindex()方法的使用
2015/05/19 Python
详解Python中的文件操作
2016/08/28 Python
如何利用Fabric自动化你的任务
2016/10/20 Python
Python+Turtle动态绘制一棵树实例分享
2018/01/16 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
2018/01/24 Python
pandas 小数位数 精度的处理方法
2018/06/09 Python
python的一些加密方法及python 加密模块
2019/07/11 Python
Python 实现将数组/矩阵转换成Image类
2020/01/09 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
Python生成器常见问题及解决方案
2020/03/21 Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
2020/04/22 Python
《最后的姿势》教学反思
2014/02/27 职场文书
信息技术课后反思
2014/04/27 职场文书
信访工作汇报材料
2014/10/27 职场文书
班主任经验交流材料
2014/12/16 职场文书
2015年教师党员公开承诺书
2015/01/22 职场文书
postgresql无序uuid性能测试及对数据库的影响
2021/06/11 PostgreSQL
Springboot如何使用logback实现多环境配置?
2021/06/16 Java/Android
opencv-python图像配准(匹配和叠加)的实现
2021/06/23 Python
python 离散点图画法的实现
2022/04/01 Python
Java中Dijkstra(迪杰斯特拉)算法
2022/05/20 Java/Android