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 08 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
比较几种Redis集群方案
Jun 21 Redis
Redis集群的关闭与重启操作
Jul 07 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
Redis模仿手机验证码发送的实现示例
Nov 02 Redis
Redis之RedisTemplate配置方式(序列和反序列化)
Mar 13 Redis
分布式架构Redis中有哪些数据结构及底层实现原理
Mar 13 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
php获取目录所有文件并将结果保存到数组(实例)
2013/10/25 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
javascript window.opener的用法分析
2010/04/07 Javascript
js 实现菜单上下显示附效果图
2013/11/21 Javascript
jquery实现的鼠标下拉滚动置顶效果
2014/07/24 Javascript
JavaScript判断变量是否为空的自定义函数分享
2015/01/31 Javascript
AngularJs解决跨域问题案例详解(简单方法)
2016/05/19 Javascript
Javascript将双字节字符转换成单字节字符并计算长度
2016/06/22 Javascript
javaScript如何跳出多重循环break、continue
2016/09/01 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
2017/03/03 Javascript
bootstrap栅格系统示例代码分享
2017/05/22 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
2018/07/26 Javascript
最简单的JS实现json转csv的方法
2019/01/10 Javascript
layui写后台表格思路和赋值用法详解
2019/11/14 Javascript
js正则匹配多个全部数据问题
2019/12/20 Javascript
jQuery操作动画完整实例分析
2020/01/10 jQuery
JS JQuery获取data-*属性值方法解析
2020/09/01 jQuery
js实现限定区域范围拖拉拽效果
2020/11/20 Javascript
Python格式化压缩后的JS文件的方法
2015/03/05 Python
python连接字符串的方法小结
2015/07/13 Python
python回调函数中使用多线程的方法
2017/12/25 Python
Python 获取中文字拼音首个字母的方法
2018/11/28 Python
python flask安装和命令详解
2019/04/02 Python
django实现模板中的字符串文字和自动转义
2020/03/31 Python
python 利用openpyxl读取Excel表格中指定的行或列教程
2021/02/06 Python
python读取图片颜色值并生成excel像素画的方法实例
2021/02/19 Python
html5 worker 实例(一) 为什么测试不到效果
2013/06/24 HTML / CSS
One.com挪威:北欧成长最快的网络托管公司
2016/11/19 全球购物
英国的一家创新礼品和小工具零售商:Menkind
2019/08/24 全球购物
元旦晚会邀请函
2014/01/27 职场文书
班队活动设计方案
2014/01/30 职场文书
2014年幼儿园国庆主题活动方案
2014/09/16 职场文书
2014党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
小区物业管理2015年度工作总结
2015/10/22 职场文书
详解在OpenCV中如何使用图像像素
2022/03/03 Python