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 12 Redis
redis cluster支持pipeline的实现思路
Jun 23 Redis
Redis入门教程详解
Aug 30 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
面试分析分布式架构Redis热点key大Value解决方案
Mar 13 Redis
源码分析Redis中 set 和 sorted set 的使用方法
Mar 22 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 Redis
windows安装 redis 6.2.6最新步骤详解
Apr 26 Redis
Redis 异步机制
May 15 Redis
Redis基本数据类型Set常用操作命令
Jun 01 Redis
浅谈Redis变慢的原因及排查方法
Jun 21 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执行速度全攻略(上)
2006/10/09 PHP
通过table标签,PHP输出EXCEL的实现方法
2013/07/24 PHP
phpinfo()中Loaded Configuration File(none)的解决方法
2017/01/16 PHP
PHP实现对数字分隔加千分号的方法
2019/03/18 PHP
Javascript new关键字的玄机 以及其它
2010/08/25 Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
2010/11/05 Javascript
ExtJs的Date格式字符代码
2010/12/30 Javascript
IE的事件传递-event.cancelBubble示例介绍
2014/01/12 Javascript
Node.js中require的工作原理浅析
2014/06/24 Javascript
第一次接触神奇的Bootstrap表单
2016/07/27 Javascript
jquery判断类型是不是number类型的实例代码
2016/10/07 Javascript
JS制作适用于手机和电脑的通知信息效果
2016/10/28 Javascript
Angular4项目中添加i18n国际化插件ngx-translate的步骤详解
2017/07/02 Javascript
基于js中this和event 的区别(详解)
2017/10/24 Javascript
vue实现商城购物车功能
2017/11/27 Javascript
vue引入新版 vue-awesome-swiper插件填坑问题
2018/01/25 Javascript
elementUI select组件value值注意事项详解
2019/05/29 Javascript
[01:32:22]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第一场 2月5日
2021/03/11 DOTA
python基础教程之简单入门说明(变量和控制语言使用方法)
2014/03/25 Python
跟老齐学Python之用while来循环
2014/10/02 Python
Python字符串切片操作知识详解
2016/03/28 Python
python 如何快速找出两个电子表中数据的差异
2017/05/26 Python
python数字图像处理实现直方图与均衡化
2018/05/04 Python
python使用Plotly绘图工具绘制水平条形图
2020/03/25 Python
Python爬虫实现的根据分类爬取豆瓣电影信息功能示例
2019/09/15 Python
使用pyqt5 tablewidget 单元格设置正则表达式
2019/12/13 Python
Python反爬虫伪装浏览器进行爬虫
2020/02/28 Python
Python3.9新特性详解
2020/10/10 Python
LocalStorage记住用户和密码功能
2017/07/24 HTML / CSS
Nike挪威官网:Nike.com (NO)
2018/11/26 全球购物
网络研修随笔感言
2014/02/17 职场文书
学校安全管理责任书
2014/07/23 职场文书
装饰技术负责人岗位职责
2015/04/13 职场文书
2015年化验室工作总结
2015/04/23 职场文书
《给予树》教学反思
2016/03/03 职场文书
Mysql开启外网访问
2022/05/15 MySQL