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的两个命令(KEYS 和 SCAN)
Apr 12 Redis
Redis6.0搭建集群Redis-cluster的方法
May 08 Redis
redis哨兵常用命令和监控示例详解
May 27 Redis
浅谈Redis的几个过期策略
May 27 Redis
详解Redis复制原理
Jun 04 Redis
Redis基于Bitmap实现用户签到功能
Jun 20 Redis
Redis缓存-序列化对象存储乱码问题的解决
Jun 21 Redis
redis不能访问本机真实ip地址的解决方案
Jul 07 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列的问题
Mar 16 Redis
redis 解决库存并发问题实现数量控制
Apr 08 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文件下载类
2006/12/06 PHP
php的memcached客户端memcached
2011/06/14 PHP
php实现编辑和保存文件的方法
2015/07/20 PHP
必须收藏的23个php实用代码片段
2016/02/02 PHP
Yii框架连接mongodb数据库的代码
2016/07/27 PHP
php处理静态页面:页面设置缓存时间实例
2017/06/22 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
PHP中类型转换 ,常量,系统常量,魔术常量的详解
2017/10/26 PHP
PHP设计模式之观察者模式定义与用法示例
2018/08/04 PHP
在JavaScript里嵌入大量字符串常量的实现方法
2013/07/07 Javascript
js实现带缓冲效果的仿QQ面板折叠菜单代码
2015/09/06 Javascript
基于JQuery实现仿网易邮箱全屏动感滚动插件fullPage
2015/09/20 Javascript
Vue.js实现移动端短信验证码功能
2017/03/29 Javascript
微信小程序表单验证错误提示效果
2017/05/19 Javascript
详解使用Node.js 将txt文件转为Excel文件
2017/07/05 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
vue监听scroll的坑的解决方法
2017/09/07 Javascript
vue使用中的内存泄漏【推荐】
2018/07/10 Javascript
JavaScript键盘事件常见用法实例分析
2019/01/03 Javascript
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
跟老齐学Python之变量和参数
2014/10/10 Python
Python利用turtle库绘制彩虹代码示例
2017/12/20 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
2018/03/05 Python
Python基础之条件控制操作示例【if语句】
2019/03/23 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
2019/07/22 Python
python如何把字符串类型list转换成list
2020/02/18 Python
18岁生日感言
2014/01/12 职场文书
俄罗斯商务邀请函
2014/01/26 职场文书
大学生会计职业生涯规划范文
2014/02/28 职场文书
求职面试个人自我评价
2014/02/28 职场文书
通用自荐信范文
2014/03/14 职场文书
初中作文评语大全
2014/04/23 职场文书
科长竞争上岗演讲稿
2014/05/12 职场文书
2016暑期校本培训心得体会
2016/01/08 职场文书
护士业务学习心得体会
2016/01/25 职场文书
Python集合的基础操作
2021/11/01 Python