使用Redis缓存实现短信登录逻辑,手机验证码缓存,用户信息缓存

引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

加配置

spring:
  redis:
    host: 127.0.0.1  #redis地址
    port: 6379 #端口
    password: 123456 #密码,无密码可以注释调
    database: 10 #库
    lettuce:
      pool:
        max-active: 10 #最大连接数
        max-idle: 10 #最多空闲
        min-idle: 1 #至少空闲
        time-between-eviction-runs: 10s #连接空闲时间

定义登录校验拦截器

/**
 * 拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
     #校验是否登录,UserHolder中使用ThreadLocal保存用户信息
     if(UserHolder.getUser() == null){ 
         response.setStatus(401); //未登录响应401状态码
         return false;
     }
        return true; //放行
    }
}

定义刷新token拦截器(只用于刷新token时间)

/**
 * 刷新token 拦截器
 */
public class RefreshTokenInterceptor implements HandlerInterceptor {
    private StringRedisTemplate stringRedisTemplate; //LoginInterceptor 是自己创建的不能autowire

    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取携带的token名
        String token = request.getHeader("authorization");
        if(StrUtil.isBlank(token)){
            return true;
        }

        //从redis中获取该token值
        String key = RedisConstants.LOGIN_USER_KEY+token;
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);
        if(StrUtil.isBlank(token)){
            return true;
        }
        //将map转Bean
        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
        UserHolder.saveUser(userDTO);
        //刷新token有效期
        stringRedisTemplate.expire(key,LOGIN_USER_TTL, TimeUnit.MINUTES);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserHolder.removeUser();
    }
}

保存用户信息类:

public class UserHolder {
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();

    public static void saveUser(UserDTO user){
        tl.set(user);
    }

    public static UserDTO getUser(){
        return tl.get();
    }

    public static void removeUser(){
        tl.remove();
    }
}

新建配置类LoginConfig,添加自己定义的拦截器


@Configuration
public class MVCConfig implements WebMvcConfigurer {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new LoginInterceptor())
            .excludePathPatterns( //添加排除路径
                "/user/code",
                "/user/login",
        ).order(1); //order值越小越先执行,值相等则先添加先执行
        
        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).order(0);
    }

}

 登录逻辑

校验手机号 --> 校验验证码 --> 检查用户是否存在 --> 生成token --> 将用户信息user转成Hash存储到redis中 --> 设置token有效期

其中token可用hutool的UUID生成: UUID.randomUUID().toString(true); //true是不要短横线 -

将用户实体转成Map集合,存放到redis中:

Map<String, Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>(),
                CopyOptions.create()
                .setIgnoreNullValue(true)
                .setFieldValueEditor((fieldName,fieldValue)-> fieldValue.toString())); //所有字段值转为String
        //存redis
        String tokenKey = LOGIN_USER_KEY + token;
        stringRedisTemplate.opsForHash().putAll(tokenKey,userMap);

 设置Token有效期

        //设置token有效期
        stringRedisTemplate.expire(tokenKey,LOGIN_USER_TTL,TimeUnit.MINUTES); //分钟

 

手机号验证,可添加一个插件,快捷查询各种校验的正则表达式:

将验证码存入redis并设置验证码有效期

         //模拟生成验证码
        String code = RandomUtil.randomNumbers(6);
        //手机号唯一
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);

常量命名规范:

    public static final String LOGIN_CODE_KEY = "login:code:"; //验证码的key
    public static final Long LOGIN_CODE_TTL = 2L; //验证码的有效期
    public static final String LOGIN_USER_KEY = "login:token:"; //token的key
    public static final Long LOGIN_USER_TTL = 30L; //token的有效期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/665753.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三十二篇:转化决策为行动:探索决策支持系统的深层价值

转化决策为行动&#xff1a;探索决策支持系统的深层价值 1. DSS的精髓&#xff1a;定义与核心功能 1.1 定义与作用 在现代商业的快速演变中&#xff0c;决策支持系统&#xff08;Decision Support Systems, DSS&#xff09;已成为企业获得竞争优势的重要工具。DSS是一种利用先…

全国产飞腾模块麒麟信安操作系统安全漏洞

1、背景介绍 目前在全国产飞腾模块上部署了麒麟信安操作系统&#xff0c;经第三方机构检测存在以下漏洞 操作系统版本为 内核版本为 openssh版本为 2、openssh CBC模式漏洞解决 首先查看ssh加密信息 nmap --script "ssh2*" 127.0.0.1 | grep -i cbc 可以通过修改/…

Elasticsearch 认证模拟题 - 5

一、题目 .在集群上有一个索引 food_ingredient&#xff0c;搜索需要满足以下要求&#xff1a; 三个字段 manufacturer&#xff0c;name&#xff0c;brand 都能匹配到文本 cake mix高亮 字段 name&#xff0c;并加标签排序&#xff0c;对字段 brand 正序&#xff0c;_score 降…

快手发布大模型产品“可图”,超20种创新AI图像玩法限免上线

近日&#xff0c;快手自研大模型产品“可图”&#xff08;Kolors&#xff09;正式对外开放&#xff0c;支持文生图和图生图两类功能&#xff0c;已上线20余种AI图像玩法。目前&#xff0c;用户可以通过“可图大模型”官方网站和微信小程序&#xff0c;免费使用各项AI图像功能。…

12k Star!Continue:Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 12k Star&#xff01;Continue&#xff1a;Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖&#xff01; &…

结构设计模式 - 代理设计模式 - JAVA

代理设计模式 一. 介绍二. 代码示例2.1 定义 CommandExecutor 类2.2 定义 CommandExecutorProxy代理类2.3 模拟客户端2.4 测试结果 三. 结论 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子…

基础—SQL—DQL(数据查询语言)分组查询

一、引言 分组查询的关键字是&#xff1a;GROUP BY。 二、DQL—分组查询 1、语法 SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ]; 注意&#xff1a; 1、[ ] 里的内容可以有可以没有。 2、这条SQL语句有两块指定条件的地方&#…

k8s的ci/cd实践之旅

书接上回k8s集群搭建完毕&#xff0c;来使用它强大的扩缩容能力帮我们进行应用的持续集成和持续部署&#xff0c;整体的机器规划如下&#xff1a; 1.192.168.8.156 搭建gitlab私服 docker pull gitlab/gitlab-ce:latest docker run --detach --hostname 192.168.8.156 --publ…

如何在Windows 10上更改默认系统字体,这里有详细步骤

Windows 10的默认系统字体Segoe UI看起来相当不错。但是,如果你有更好的替代品,你可以更改Windows 10 PC上的默认系统字体。我们将向你展示如何执行此操作。 如何使用注册表编辑器更改默认系统字体 在撰写本文时,“设置”和“控制面板”都没有更改默认系统字体的选项。这意…

【评价类模型】熵权法

1.客观赋权法&#xff1a; 熵权法是一种客观求权重的方法&#xff0c;所有客观求权重的模型中都要有以下几步&#xff1a; 1.正向化处理&#xff1a; 极小型指标&#xff1a;取值越小越好的指标&#xff0c;例如错误率、缺陷率等。 中间项指标&#xff1a;取值在某个范围内较…

电子阅览室能给孩子做什么

电子阅览室为孩子提供了很多活动和资源&#xff0c;可以为他们提供以下服务&#xff1a; 1. 提供电子书籍和儿童读物&#xff1a;电子阅览室通常提供大量的电子书籍和儿童读物&#xff0c;供孩子选择阅读。 2. 提供儿童学习资源&#xff1a;专久智能电子阅览室可以提供各种学习…

HarmonyOS 鸿蒙应用开发( 五、快速实现ArkUI页面底部导航Tabs)

当页面信息较多时&#xff0c;为了让用户能够聚焦于当前显示的内容&#xff0c;需要对页面内容进行分类&#xff0c;提高页面空间利用率。Tabs组件可以在一个页面内快速实现视图内容的切换&#xff0c;一方面提升查找信息的效率&#xff0c;另一方面精简用户单次获取到的信息量…

神经网络与深度学习——第14章 深度强化学习

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第14章 深度强化学习 深度强化学习 强化学习&#xff08;Reinforcement Learning&#xff0c;RL&#xff09;&#xff0c;也叫增强学习&#xff0c;是指一类从与环境交互中不断学习的问题以及解决这类问题…

关于MD5

首先还是介绍一下关于md5的基本信息&#xff1a; MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常用的哈希函数&#xff0c;用于产生128位&#xff08;16字节&#xff09;的哈希值&#xff0c;通常以32个十六进制数字表示。MD5广泛用于计算文件或文本数据的校…

【SQL学习进阶】从入门到高级应用(九)

文章目录 子查询什么是子查询where后面使用子查询from后面使用子查询select后面使用子查询exists、not existsin和exists区别 union&union alllimit &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f495;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面…

计算机视觉与模式识别实验1-2 图像的形态学操作

文章目录 &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1;1.图像膨胀2.图像腐蚀3.膨胀与腐蚀的综合使用4.对下面二值图像的目标提取骨架&#xff0c;并分析骨架结构。 &#x1f9e1;&#x1f9e1;全部代码&#x1f9e1;&#x1f9e1; &#x1f9e1;&#x1f9e1…

Unity实现简单的第一人称控制

先看效果 实现方式 1.首先创建一个脚本 2.编辑脚本内容 付上脚本代码 private float RotationX 0;public float speed 2f;//移动速度// Use this for initializationvoid Start(){Cursor.lockState CursorLockMode.Locked;//锁定鼠标到中心点Cursor.visible false;//隐藏鼠…

前端Vue小兔鲜儿电商项目实战Day03

一、Home - 整体结构搭建和分类实现 1. 页面结构 ①按照结构新增5个组件&#xff0c;准备最简单的模板&#xff0c;分别在Home模块的入口组件中引入 src/views/Home/components/ HomeCategory.vue HomeBanner.vue HomeNew.vue HomeHot.vue HomeProduct.vue <script …

eNSP学习——OSPF的DR与BDR

目录 相关命令 原理概述 实验内容 实验目的 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建基本的OSPF网络 3、查看默认情况下的DR/BDR状态 4、根据现网需求影响DR/BDR选举 相关命令 [R4]int g0/0/0 [R4-GigabitEthernet0/0/0]ospf network-type p2mp //在接…

Golang:使用Base64Captcha生成数字字母验证码实现安全校验

Base64Captcha可以在服务端生成验证码&#xff0c;以base64的格式返回 为了能看到生成的base64验证码图片&#xff0c;我们借助gin go get -u github.com/mojocn/base64Captcha go get -u github.com/gin-gonic/gin文档的示例看起来很复杂&#xff0c;下面&#xff0c;通过简…