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限流的实际应用
Apr 24 Redis
Redis6.0搭建集群Redis-cluster的方法
May 08 Redis
redis三种高可用方式部署的实现
May 11 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
Redis高级数据类型Hyperloglog、Bitmap的使用
May 24 Redis
详解Redis集群搭建的三种方式
May 31 Redis
浅谈Redis位图(Bitmap)及Redis二进制中的问题
Jul 15 Redis
使用RedisTemplat实现简单的分布式锁
Nov 20 Redis
Springboot/Springcloud项目集成redis进行存取的过程解析
Dec 04 Redis
解决 redis 无法远程连接
May 15 Redis
Redis批量生成数据的实现
Jun 05 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 #Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
You might like
关于PHP5 Session生命周期介绍
2010/03/02 PHP
使用gd库实现php服务端图片裁剪和生成缩略图功能分享
2013/12/25 PHP
非常实用的php弹出错误警告函数扩展性强
2014/01/17 PHP
PHP文件系统管理(实例讲解)
2017/09/19 PHP
Yii2框架实现登录、退出及自动登录功能的方法详解
2017/10/24 PHP
Javascript模板技术
2007/04/27 Javascript
event.keyCode键码值表 附只能输入特定的字符串代码
2009/05/15 Javascript
Javascript 加载和执行-性能提高篇
2012/12/28 Javascript
JavaScript实现找出字符串中第一个不重复的字符
2014/09/03 Javascript
javascript中局部变量和全局变量的区别详解
2015/02/27 Javascript
jQuery实现tab标签自动切换的方法
2015/02/28 Javascript
JavaScript中的parse()方法使用简介
2015/06/12 Javascript
理解和运用JavaScript的闭包机制
2015/08/13 Javascript
基于nodejs+express(4.x+)实现文件上传功能
2015/11/23 NodeJs
JS实现的几个常用算法
2016/11/12 Javascript
很棒的一组js图片轮播特效
2017/01/12 Javascript
Js自动截取字符串长度,添加省略号(……)的实现方法
2017/03/06 Javascript
Vue实现todolist删除功能
2018/06/26 Javascript
微信公众号平台接口开发 获取access_token过程解析
2019/08/14 Javascript
Python过滤函数filter()使用自定义函数过滤序列实例
2014/08/26 Python
利用Python爬取可用的代理IP
2016/08/18 Python
利用python将xml文件解析成html文件的实现方法
2017/12/22 Python
用Python将mysql数据导出成json的方法
2018/08/21 Python
在VS2017中用C#调用python脚本的实现
2019/07/31 Python
python matplotlib库直方图绘制详解
2019/08/10 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
基于pandas中expand的作用详解
2019/12/17 Python
selenium 多窗口切换的实现(windows)
2020/01/18 Python
DataFrame 数据合并实现(merge,join,concat)
2020/06/14 Python
清除canvas画布内容(点擦除+线擦除)
2020/08/12 HTML / CSS
阿联酋团购网站:Groupon阿联酋
2016/10/14 全球购物
统计系教授推荐信
2014/02/28 职场文书
银行金融服务方案
2014/06/11 职场文书
PyQt5 QThread倒计时功能的实现代码
2021/04/02 Python
浅谈MySQL之浅入深出页原理
2021/06/23 MySQL
「玫瑰之王的葬礼」舞台剧主视觉图公开
2022/03/21 日漫