使用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 {@Overridepublic 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 是自己创建的不能autowirepublic RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}@Overridepublic 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转BeanUserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);UserHolder.saveUser(userDTO);//刷新token有效期stringRedisTemplate.expire(key,LOGIN_USER_TTL, TimeUnit.MINUTES);return true;}@Overridepublic 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 {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic 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//存redisString 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:"; //验证码的keypublic static final Long LOGIN_CODE_TTL = 2L; //验证码的有效期public static final String LOGIN_USER_KEY = "login:token:"; //token的keypublic static final Long LOGIN_USER_TTL = 30L; //token的有效期
相关文章:
使用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 #密码…...
探索未来制造,BFT Robotics引领潮流
“买机器人,上BFT” 在这个快速变化的时代,创新和效率是企业发展的关键。BFT Robotics,作为您值得信赖的合作伙伴,专注于为您提供一站式的机器人采购和自动化解决方案。 产品系列: 协作机器人:安全、灵活、…...
数组中的第K个最大元素 ---- 分治-快排
题目链接 题目: 分析: 这道题很明显是一个top-K问题, 我们很容易想到用堆排序来解决, 堆排序的时间复杂度是O(N*logN), 不符合题意, 所以我们可以用另一种方法:快速选择算法, 他的时间复杂度为O(N)快速选择算法, 其实是基于快排, 进行修改而成, 我们还是使用将"将数组分…...
函数或变量 ‘tfrstft‘ 无法识别
参考博客 Matlab时频工具箱tftb下载及安装_tftb工具箱-CSDN博客 解决。...
在推荐四款软件卸载工具,让流氓软件无处遁形
Revo Uninstaller Revo Uninstaller是一款电脑软件、浏览器插件卸载软件,目前已经有了17年的历史了。可以扫描所有window用户卸载软件后的残留物,并及时清理,避免占用电脑空间。 Revo Uninstaller可以通过命令行卸载软件,可以快速…...
「前端+鸿蒙」核心技术HTML5+CSS3(十一)
1、CSS3 简介 CSS3 是层叠样式表的最新标准,它引入了许多新特性来增强网页的表现力。CSS3 不仅增强了现有CSS属性的功能,还引入了新的布局方式、动画、渐变、阴影、边框效果等。 2、CSS3 长度单位 CSS3 引入了一些新的单位,包括但不限于: vw(视口宽度的百分比)vh(视口…...
【高频】如何优化一个SQL语句
使用合适的索引:确保查询中涉及的字段上有合适的索引,避免全表扫描。可以通过 EXPLAIN 命令来查看查询执行计划,判断是否使用了索引。 避免使用通配符查询:尽量避免在查询条件中使用通配符(如 %)ÿ…...
Oracle EBS AP发票创建会计科目提示:APP-SQLAP-10710:无法联机创建会计分录
系统版本 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 问题症状: 提交“创建会计科目”请求提示错误信息如下: APP-SQLAP-10710:无法联机创建会计分录。 请提交应付款管理系统会计流程,而不要为此事务处理创建会计分录解决方法 数据修复SQL脚本: UPDATE ap_invoi…...
T-Pot多功能蜜罐实践@debian12@FreeBSD
T-Pot介绍 T-Pot是一个集所有功能于一身的、可选择分布式的多构架(amd64,arm64)蜜罐平台,支持20多个蜜罐和很多可视化选项,使用弹性堆栈、动画实时攻击地图和许多安全工具来进一步改善欺骗体验。GitHub - telekom-sec…...
Sed流编辑器总结
sed 是 Unix 和 Linux 系统中的一个强大的流编辑器。它用于对文本进行基本的修改和处理。以下是关于 sed 的详细解说,包括其基本语法,常见用法和一些高级用法。 基本语法 sed [选项] 命令 输入文件常见选项 -e:指定要执行的 sed 命令。-f&a…...
智合同丨AIGC如何助力合同智能应用
#AIGC #合同智能应用 #智合同 AIGC,即人工智能生成内容技术(Artificial Intelligence Generated Content),近期在各个领域发展可谓是如火如荼,那么它在合同智能应用方面可以提供哪些助力? 让我们和智合…...
CSRF 令牌的生成过程和检查过程
在 Django 中,CSRF 令牌的生成和检查过程是通过 Django 的 CSRF 中间件 (CsrfViewMiddleware) 和模板标签 ({% csrf_token %}) 自动处理的。以下是详细的生成和检查过程: CSRF 令牌的生成过程 用户访问页面: 当用户第一次访问页面时,Django 会为用户创建一个会话。如果用户…...
计算机网络学习记录 网络层 Day4(下)
计算机网络学习记录 网络层 Day4 (下) 你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我…...
3、前端本地环境搭建
前端本地环境搭建 安装node [node下载地址] https://nodejs.org/en/download/prebuilt-installer 选择LTS的版本进行下载 下载后直接双击点击,选择自己想要安装到的目录一直点下一步即可(建议不要安装到c盘) 安装完成后配置环境变量&am…...
Python爬取城市空气质量数据
Python爬取城市空气质量数据 一、思路分析1、寻找数据接口2、发送请求3、解析数据4、保存数据二、完整代码一、思路分析 目标数据所在的网站是天气后报网站,网址为:www.tianqihoubao.com,需要采集武汉市近十年每天的空气质量数据。先看一下爬取后的数据情况: 1、寻找数据…...
【MyBatisPlus条件构造器】
文章目录 什么是条件构造器?使用步骤1. 引入 MyBatisPlus 依赖2. 创建实体类3. 使用条件构造器查询4. 执行查询 示例代码 什么是条件构造器? 条件构造器是 MyBatisPlus 提供的一种灵活的查询条件设置方式,它可以帮助开发者构建复杂的查询条件…...
容器多机部署eureka及相关集群服务出现 Request execution failed with message: AuthScheme is null
预期部署方案:两个eureka三个相关应用 注册时应用出现:Request execution failed with message: Cannot invoke “Object.getClass()” because “authScheme” is null,一开始认为未正确传递eureka配置的账户密码,例:…...
Qt Graphics View Framework 使用教程
欢迎来到 Qt Graphics View Framework 的世界!本教程将引导您了解这一强大工具的基础知识,并教您如何开始使用它来创建丰富的 2D 图形界面。无论您是编程新手还是经验丰富的开发者,本教程都将帮助您快速上手。 基本概念 Qt Graphics View F…...
【调试笔记-20240606-Linux-为 OpenWrt 的 nginx 服务器添加Shell CGI 支持】
调试笔记-系列文章目录 调试笔记-20240606-Linux-为 OpenWrt 的 nginx 服务器添加Shell CGI 支持 文章目录 调试笔记-系列文章目录调试笔记-20240606-Linux-为 OpenWrt 的 nginx 服务器添加Shell CGI 支持 前言一、调试环境操作系统:Windows 10 专业版调试环境调试…...
flink实战--⼤状态作业调优实践指南-Flink SQL 作业篇
简介 作为一种特定领域语言,SQL 的设计初衷是隐藏底层数据处理的复杂性,让用户通过声明式语言来进行数据操作。而Flink SQL 由于其架构的特殊性,在实现层面通常需引入状态后端 配合 checkpoint 来保证计算结果的最终一致性。目前 Flink SQL 生成状态算子的策略由优化器根据配…...
FcμR识别IgM复杂机制的揭示:解锁人体免疫早期应答之谜
一、引言免疫系统是机体抵御病原体入侵、维持内环境稳定的关键防线。在免疫应答过程中,不同类型的免疫球蛋白发挥着独特的作用。其中,IgM作为人体五类免疫球蛋白之一,在免疫应答早期起着至关重要的作用。而Fc受体作为免疫系统中的重要组成部分…...
告别枯燥理论:用Verilog在FPGA上实现一个可交互的I2C温度传感器从机
从零构建FPGA上的智能温度传感器:Verilog I2C从机实战指南 当你想在FPGA上连接一个温度传感器时,市面上常见的I2C传感器如LM75似乎是个简单选择——但你是否想过,用Verilog自己实现一个会是什么体验?本文将带你从协议层开始&#…...
Adobe-GenP 3.0:三步解锁Adobe全家桶的终极指南
Adobe-GenP 3.0:三步解锁Adobe全家桶的终极指南 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP 还在为昂贵的Adobe Creative Cloud订阅费而烦恼吗&#…...
基于 DWT 的盲数字水印实现(嵌入与提取)
一、原理 盲数字水印(Blind Watermarking)指提取水印时无需原始载体图像,仅依靠含水印图像和密钥即可完成。 DWT(离散小波变换) 将图像分解为: LL:低频近似分量(能量集中,…...
AI辅助开发工作流:用免费代理优化付费工具,提升代码生成效率
1. 项目概述:用免费AI代理优化付费AI工具的开发工作流如果你和我一样,订阅了Claude Pro或者GitHub Copilot,但每个月看着额度条飞速见底,心里总有点发慌,那这篇文章就是为你准备的。我们不是在讨论哪个AI写代码更强&am…...
GitHub企业版MCP服务器:为AI助手集成私有化GitHub工作流
1. 项目概述:一个为开发者定制的GitHub企业版MCP服务器如果你是一名重度依赖GitHub Enterprise进行团队协作的开发者,并且正在探索如何将AI助手(比如Claude、Cursor等)无缝集成到你的日常开发工作流中,那么你很可能已经…...
蓝奏云直链解析:从繁琐到一键的下载革命
蓝奏云直链解析:从繁琐到一键的下载革命 【免费下载链接】LanzouAPI 蓝奏云直链,蓝奏api,蓝奏解析,蓝奏云解析API,蓝奏云带密码解析 项目地址: https://gitcode.com/gh_mirrors/la/LanzouAPI 你是否厌倦了蓝奏云…...
基于T4技术栈的现代全栈应用开发实践与最佳实践解析
1. 项目概述:一个现代全栈应用的原型与起点最近在GitHub上看到一个挺有意思的项目,叫timothymiller/t4-app。乍一看这个名字,可能有点摸不着头脑,但点进去你会发现,这其实是一个精心设计的全栈Web应用模板。它不是某个…...
现实是期待的土壤,期待是改变现实的方向
期待的对立统一结构期待 理想应然(正题) vs 现实实然(反题),二者的统一构成一个动态的矛盾运动。同一性(相互依存):没有对现实的不满足和对未来的向往,就没有期待&#…...
告别手动传包!用Pypiserver在内网搭建Python私有源,团队协作效率翻倍
告别手动传包!用Pypiserver在内网搭建Python私有源,团队协作效率翻倍 在团队开发中,Python依赖管理常常成为效率瓶颈。想象这样的场景:新同事加入项目,需要配置开发环境,却因为内网限制无法直接访问PyPI&a…...
