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通过6379端口无法连接服务器(redis-server.exe闪退)
May 08 Redis
Redis数据结构之链表与字典的使用
May 11 Redis
浅谈redis缓存在项目中的使用
May 20 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
深入理解redis中multi与pipeline
Jun 02 Redis
CentOS8.4安装Redis6.2.6的详细过程
Nov 20 Redis
redis击穿 雪崩 穿透超详细解决方案梳理
Mar 17 Redis
redis复制有可能碰到的问题汇总
Apr 03 Redis
windows安装 redis 6.2.6最新步骤详解
Apr 26 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
基于redis+lua进行限流的方法
Jul 23 Redis
Redis配置外网可访问(redis远程连接不上)的方法
Dec 24 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
小偷PHP+Html+缓存
2006/12/20 PHP
php heredoc和phpwind的模板技术使用方法小结
2008/03/28 PHP
php 无极分类(递归)实现代码
2010/01/05 PHP
yii框架中的Url生产问题小结
2012/01/16 PHP
微信企业转账之入口类分装php代码
2018/10/01 PHP
让浏览器非阻塞加载javascript的几种方法小结
2011/04/25 Javascript
js 函数的副作用分析
2011/08/23 Javascript
jQuery-serialize()输出序列化form表单值的方法
2012/12/26 Javascript
js日期时间补零的小例子
2013/03/05 Javascript
javascript设计模式之解释器模式详解
2014/06/05 Javascript
Javascript动态创建div的方法
2015/02/09 Javascript
以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题
2015/11/13 Javascript
javascript实现移动端上的触屏拖拽功能
2016/03/04 Javascript
Vue实现路由跳转和嵌套
2017/06/20 Javascript
使用 jQuery 实现表单验证功能
2017/07/05 jQuery
微信小程序时间戳转日期的详解
2019/04/30 Javascript
通过js实现压缩图片上传功能
2020/02/25 Javascript
微信小程序地图实现展示线路
2020/07/29 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
Python中的Matplotlib模块入门教程
2015/04/15 Python
python将字符串转换成数组的方法
2015/04/29 Python
Python中修改字符串的四种方法
2018/11/02 Python
python 读取更新中的log 或其它文本方式
2019/12/24 Python
python如何操作mysql
2020/08/17 Python
flask项目集成swagger的方法
2020/12/09 Python
迪斯尼商品官方网站:ShopDisney
2016/08/01 全球购物
应届毕业生求职信
2013/11/30 职场文书
技校个人求职信范文
2014/01/25 职场文书
店面销售职位的职责
2014/03/09 职场文书
捐款倡议书
2014/04/14 职场文书
环境整治工作方案
2014/05/18 职场文书
如何写辞职信
2015/05/13 职场文书
2016学习依法治国心得体会
2016/01/15 职场文书
医护人员继续教育学习心得体会
2016/01/19 职场文书
餐厅开业活动方案
2019/07/08 职场文书
用Python实现屏幕截图详解
2022/01/22 Python