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 查看所有的key方式
May 07 Redis
深入浅析Redis 集群伸缩原理
May 15 Redis
5分钟教你docker安装启动redis全教程(全新方式)
May 29 Redis
redis使用不当导致应用卡死bug的过程解析
Jul 01 Redis
Redis 彻底禁用RDB持久化操作
Jul 09 Redis
Redis做数据持久化的解决方案及底层原理
Jul 15 Redis
缓存替换策略及应用(以Redis、InnoDB为例)
Jul 25 Redis
redis中lua脚本使用教程
Nov 01 Redis
Redis 的查询很快的原因解析及Redis 如何保证查询的高效
Mar 16 Redis
Redis高可用集群redis-cluster详解
Mar 20 Redis
在Centos 8.0中安装Redis服务器的教程详解
Mar 21 Redis
Redis分布式锁的7种实现
Apr 01 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
2013/02/06 PHP
php延迟静态绑定实例分析
2015/02/08 PHP
PHP开发中csrf攻击的简单演示和防范
2017/05/07 PHP
php中关于换行的实例写法
2019/09/26 PHP
js checkbox(复选框) 使用集锦
2009/04/28 Javascript
jquery怎样实现ajax联动框(二)
2013/03/08 Javascript
基于jQuery中对数组进行操作的方法
2013/04/16 Javascript
使用jquery写个更改表格行顺序的小功能
2014/04/29 Javascript
window.open打开窗口被拦截的快速解决方法
2016/08/04 Javascript
JavaScript数据结构链表知识详解
2016/11/21 Javascript
Angularjs+bootstrap+table多选(全选)支持单击行选中实现编辑、删除功能
2017/03/27 Javascript
ES5 ES6中Array对象去除重复项的方法总结
2017/04/27 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
深入学习Vue nextTick的用法及原理
2019/10/08 Javascript
微信小程序canvas截取任意形状的实现代码
2020/01/13 Javascript
js判断在哪个浏览器打开项目的方法
2020/01/21 Javascript
vue项目实现多语言切换的思路
2020/09/17 Javascript
Linux CentOS7下安装python3 的方法
2018/01/21 Python
python利用7z批量解压rar的实现
2019/08/07 Python
详解Python self 参数
2019/08/30 Python
python实现把两个二维array叠加成三维array示例
2019/11/29 Python
python实现录屏功能(亲测好用)
2020/03/02 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
2020/06/15 Python
Pycharm打开已有项目配置python环境的方法
2020/07/03 Python
基于Jquery和Css3代码制作可以缩放的搜索框
2015/11/19 HTML / CSS
小程序瀑布流解决左右两边高度差距过大的问题
2019/02/20 HTML / CSS
植物选择:Botanic Choice
2017/02/15 全球购物
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
新西兰珠宝品牌:Michael Hill
2017/09/16 全球购物
法国大使拉杆箱官网:DELSEY Paris
2018/03/20 全球购物
什么是托管函数?托管函数有什么用?
2014/06/15 面试题
大学毕业感言
2014/01/10 职场文书
2014年幼儿园植树节活动方案
2014/03/02 职场文书
爱与责任师德演讲稿
2014/08/26 职场文书
社区敬老月活动总结
2015/05/07 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书