使用redis实现手机短信验证码和lua完成重置功能

文章目录

  • 前言
  • 一、介绍
  • 二、代码
    • 1.LoginController
    • 2.reset.lua
  • 总结


前言

2024了,各种各样的门户网站和APP都需要登录,登录方式也各种各样,由于都要绑定用户手机号码,所以大部分都支持了手机验证码登录的方式,接下来我们使用redis来完成验证码的功能。


一、介绍

方法名描述
get获取验证码
match验证码配对
reset验证码重置
check手机号检测
sendVerificationCode发送验证码

二、代码

1.LoginController

@Controller
@RequestMapping("verificationCode")
public class LoginController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;private int maxRetryCount=3;private static final String COUNT="_COUNT";private static final String CODE="_CODE";private static final DefaultRedisScript<Boolean> RESET_SCRIPT;static {RESET_SCRIPT = new DefaultRedisScript<>();RESET_SCRIPT.setLocation(new ClassPathResource("redis/reset.lua"));RESET_SCRIPT.setResultType(Boolean.class);}@RequestMapping("get")@ResponseBodypublic boolean get(String phone){Optional.of(phone);if(check(phone)){return sendVerificationCode(phone);}return false;}@RequestMapping("match")@ResponseBodypublic boolean match(String phone, String code) {String redisCode = stringRedisTemplate.opsForValue().get(phone + CODE);System.out.println("用户["+phone+"],认证完成,跳转到首页!");return code.equals(redisCode);}@RequestMapping("reset")@ResponseBodypublic boolean reset(String phone) {boolean res=false;try {//用手机号拼接上字符串来作为key值,这是作为发送的次数String countKey = phone + COUNT;//用手机号拼接上字符串来作为key值,来表示你的验证码String codeKey = phone + CODE;if(stringRedisTemplate.execute(RESET_SCRIPT,Arrays.asList(countKey, codeKey))){res=true;System.out.println("重置已完成");}}catch (Exception e){e.printStackTrace();}return res;}private boolean check(String phone) {String regex = "^1[0-9]{10}$"; // 定义手机号格式的正则表达式Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(phone);return matcher.matches();}private boolean sendVerificationCode(String phone){//用手机号拼接上字符串来作为key值,这是作为发送的次数String countKey = phone + COUNT;//用手机号拼接上字符串来作为key值,来表示你的验证码String codeKey = phone + CODE;try {//根据countKey来获取发送的次数String countStr = stringRedisTemplate.opsForValue().get(countKey);Integer count;try {//将String类型的次数来强转为Integercount = Integer.valueOf(countStr);}catch (NumberFormatException e){count = 0;}if(count > maxRetryCount){System.out.println("24小时内短信发送次数已达"+maxRetryCount+"次,不能继续发送!24小时后自动重置次数");//做判断来表示发送三次,再次发送失败return false;}//判断codeKey是否存在boolean isTtl = stringRedisTemplate.hasKey(codeKey);if(isTtl){//如果存在的获取还有多少秒过期long ttlCode = stringRedisTemplate.getExpire(codeKey);System.out.println("验证码在1分钟内保持有效,请于"+ttlCode+"秒之后再次发送");return false;}//获取6位数的随机数//这个地方如果换成手机短信的api接口的话就可以实现手机短信验证的功能String code = RandomUtil.randomNumbers(6);//保存在随机数中设置过期时间stringRedisTemplate.opsForValue().set(codeKey,code,1, TimeUnit.MINUTES);//设置过期时间为1天long timeOut = 24 * 60 * 60;//做一个判断如果不是第一次发送,就要根据countKey来获取他的剩余的过期时间if(count!=0){//如果这个地方是短信验证的功能的话就是可以换成根据countKey来获取它是否存在来判断是否验证码过期timeOut = stringRedisTemplate.getExpire(countKey);}stringRedisTemplate.opsForValue().set(countKey,String.valueOf(count+1),timeOut,TimeUnit.SECONDS);System.out.println("短信验证码发送完毕!请注意查收!");return true;}catch (Exception e){stringRedisTemplate.delete(codeKey);stringRedisTemplate.delete(countKey);return false;}}
}

2.reset.lua

-- reset.lua
local count = redis.call('get',KEYS[1])
if (count ~= nil) thenredis.call('del',KEYS[1])
end
local code = redis.call('get',KEYS[2])
if (code ~= nil) thenredis.call('del',KEYS[2])
end
return true

总结

回到顶部
官方文档对脚本的描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习入门-第2章-感知机

感知机&#xff08;perceptron&#xff09; 严格地讲&#xff0c;本章中所说的感知机应该称为“人工神经元”或“朴素感知机”&#xff0c;但是因为很多基本的处理都是共通的&#xff0c;所以这里就简单地称为“感知机”。2.1 感知机是什么 感知机接收多个输入信号&#xff0c…

Uipath 实现Excel 文件合并

场景描述 某文件夹下有多个相同结构(标题列相同)的Excel 文件&#xff0c;需实现汇总到一个Excel文件。 常见场景有销售明细汇总&#xff0c;订单汇总等。 解决方案 对于非IT 人员则可使用Uipath 新式Excel活动&#xff0c;通过拖拉实现。也可以通过内存表或使用VB脚本&…

解锁机器学习多类分类之门:Softmax函数的全面指南

1. 引言 Softmax函数的定义和基本概念 Softmax函数&#xff0c;也称为归一化指数函数&#xff0c;是一个将向量映射到另一个向量的函数&#xff0c;其中输出向量的元素值代表了一个概率分布。在机器学习中&#xff0c;特别是在处理多类分类问题时&#xff0c;Softmax函数扮演…

寒假学习记录17:包管理器(包管理工具)

概念 包&#xff08;package&#xff09; 包含元数据的库&#xff0c;这些元数据包括&#xff1a;名称&#xff0c;描述&#xff0c;git主页&#xff0c;许可证协议&#xff0c;作者&#xff0c;依赖..... 库&#xff08;library&#xff0c;简称lib&#xff09; 以一个或多个模…

第11讲投票创建后端实现

投票创建页面实现 文件选择上传组件 uni-file-picker 扩展组件 安装 https://ext.dcloud.net.cn/plugin?nameuni-file-picker 日期选择器uni-datetime-picker组件 安装 https://ext.dcloud.net.cn/plugin?nameuni-datetime-picker iconfont小图标 https://www.iconfont…

【教3妹学编程-算法题】子集中元素的最大数量

2哥 : 3妹&#xff0c;今年过年收到压岁钱了没呢。 3妹&#xff1a;切&#xff0c;我都多大了啊&#xff0c;肯定没收了啊 2哥 : 俺也一样&#xff0c;不仅没收到&#xff0c;小侄子小外甥都得给&#xff0c;还倒贴好几千 3妹&#xff1a;哈哈哈哈&#xff0c;2叔叔&#xff0c…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Navigation组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Navigation组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Navigation组件 鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#…

Java:性能优化细节01-10

Java&#xff1a;性能优化细节01-10 在Java程序开发过程中&#xff0c;性能优化是一个重要的考虑因素。常见的误解是将性能问题归咎于Java语言本身&#xff0c;然而实际上&#xff0c;性能瓶颈更多地源于程序设计和代码实现方式的不当。因此&#xff0c;培养良好的编码习惯不仅…

(力扣记录)235. 二叉搜索树的最近公共祖先

数据结构&#xff1a;树&#x1f332; 时间复杂度&#xff1a;O(n) 空间复杂度&#xff1a;O(1) 代码实现&#xff1a; class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:while True:if p.val < root.val <…

数据的艺术与保障:深入探索OSI模型的表示层

引言 在现代计算机网络中&#xff0c;数据的传输和交换是至关重要的。为了促进不同计算机系统之间的有效通信&#xff0c;国际标准化组织&#xff08;ISO&#xff09;提出了开放系统互连&#xff08;OSI&#xff09;参考模型。该模型定义了网络通信的七个层次&#xff0c;每一…

Python中多种生成随机密码超实用实例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 前言 密码是信息安全的基石&#xff0c;它用于保护我们的账户、数据和隐私。为了确保密码足够强大&#xff0c;…

我的大数据之路 - 基于HANA构建实时方案的历程

产品内部前期有一个共识&#xff0c;依据业务要求的时效性来选择技术平台&#xff0c;即&#xff1a; 实时类业务&#xff0c;时效性小于2小时&#xff0c;则使用HANA构建。离线类业务&#xff0c;时效性大于2小时&#xff0c;则使用大数据平台构建。 经过五月、六月两月的努…

今日JAVA小练习之复制数组

题目描述 将两个有序数组按照大小顺序复制成一个数组 实现思路 创建新的数组&#xff0c;长度为要复制的两个数组长度之和定义3个初始变量i,p1,p2在循环中依次比较两个数组中元素大小&#xff0c;小的放入新数组若p1小于ns1的长度&#xff0c;则说明在上面while循环中ns1的元…

Redis 的 SETNX

Redis 的 SETNX 命令是一个用于设置键的值的原子性操作。SETNX 表示 "SET if Not eXists"&#xff0c;即当键不存在时才进行设置。该命令可以实现一种简单的分布式锁和限流策略。 SETNX 命令的语法如下&#xff1a; 复制代码 SETNX key value key&#xff1a;要设…

clang前端

Clang可以处理C、C和Objective-C源代码 Clang简介 Clang可能指三种不同的实体&#xff1a; 前端&#xff08;在Clang库中实现&#xff09;编译驱动程序&#xff08;在clang命令和Clang驱动程序库中实现&#xff09;实际的编译器&#xff08;在clang-ccl命令中实现&#xff0…

kafka如何保证消息不丢?

概述 我们知道Kafka架构如下&#xff0c;主要由 Producer、Broker、Consumer 三部分组成。一条消息从生产到消费完成这个过程&#xff0c;可以划分三个阶段&#xff0c;生产阶段、存储阶段、消费阶段。 产阶段: 在这个阶段&#xff0c;从消息在 Producer 创建出来&#xff0c;…

c++阶梯之类与对象(下)

前文&#xff1a; c阶梯之类与对象&#xff08;上&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;&#xff1c; 续集 &#xff1e;-CSDN博客 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&a…

Windows注册表的参数,比如: %* %0 %1 %2 %D %L %V %W

Windows注册表的参数,比如: %* %0 %1 %2 %D %L %V %W 参数意义%*代表所有的参数%0, %1第1个&#xff08;文件&#xff09;参数的完整路径&#xff0c;不包含引号。当应用程序是16位时&#xff0c;得到8.3短路径形式&#xff1b;当应用程序是32/64位时&#xff0c;得到长路径。…

【机器学习笔记】3 逻辑回归

分类问题 分类问题监督学习最主要的类型&#xff0c;主要特征是标签离散&#xff0c;逻辑回归是解决分类问题的常见算法&#xff0c;输入变量可以是离散的也可以是连续的 二分类 先从用蓝色圆形数据定义为类型1&#xff0c;其余数据为类型2&#xff1b;只需要分类1次&#x…

寒假 14

1.请编程实现二维数组的杨慧三角 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <unistd.h> int main(int argc, const char *argv[]) {int n;printf("please enter n:");scanf("%d&q…