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
为Java项目添加Redis缓存的方法
May 18 Redis
Redis 配置文件重要属性的具体使用
May 20 Redis
redis实现排行榜功能
May 24 Redis
Redis基于Bitmap实现用户签到功能
Jun 20 Redis
解析Redis Cluster原理
Jun 21 Redis
关于redisson缓存序列化几枚大坑说明
Aug 04 Redis
redis的list数据类型相关命令介绍及使用
Jan 18 Redis
使用Redis做预定库存缓存功能
Apr 02 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis基本数据类型Zset有序集合常用操作
Jun 01 Redis
如何使用注解方式实现 Redis 分布式锁
Jul 23 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
Mysql的GROUP_CONCAT()函数使用方法
2008/03/28 PHP
php中设置index.php文件为只读的方法
2013/02/06 PHP
深入解析php中的foreach问题
2013/06/30 PHP
一个经典实用的PHP图像处理类分享
2014/11/18 PHP
PHP+AJAX实现投票功能的方法
2015/09/28 PHP
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
input、button的不同type值在ajax提交表单时导致的陷阱
2009/02/24 Javascript
最短的javascript:地址栏载入脚本代码
2011/10/13 Javascript
DOM基础教程之使用DOM控制表格
2015/01/20 Javascript
JavaScript使用FileSystemObject对象写入文本文件内容的方法
2015/08/05 Javascript
学习JavaScript设计模式(封装)
2015/11/26 Javascript
基于IView中on-change属性的使用详解
2018/03/15 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
2018/10/08 Javascript
angular4 获取wifi列表中文显示乱码问题的解决
2018/10/20 Javascript
JS实现音乐导航特效
2020/01/06 Javascript
使用typescript改造koa开发框架的实现
2020/02/04 Javascript
js+canvas实现纸牌游戏
2020/03/16 Javascript
在vue中封装方法以及多处引用该方法详解
2020/08/14 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
2020/08/25 Javascript
python使用三角迭代计算圆周率PI的方法
2015/03/20 Python
对Python中创建进程的两种方式以及进程池详解
2019/01/14 Python
如何使用Python实现自动化水军评论
2019/06/26 Python
python文字转语音实现过程解析
2019/11/12 Python
python迭代器常见用法实例分析
2019/11/22 Python
python读取xml文件方法解析
2020/08/04 Python
Python之字典添加元素的几种方法
2020/09/30 Python
意大利奢华内衣制造商:Cosabella
2017/08/29 全球购物
学雷锋标兵事迹材料
2014/08/18 职场文书
学习焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
贵阳市党的群众路线教育实践活动党(工)委领导班子整改方案
2014/10/26 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
前台接待岗位职责范本
2015/04/03 职场文书
2015入党自传书范文
2015/06/26 职场文书
暑假生活随笔
2015/08/15 职场文书
护士心得体会范文
2016/01/25 职场文书
一定要知道的 25 个 Vue 技巧
2021/11/02 Vue.js