当前位置: 首页 > news >正文

springboot系列(二十):如何通过redis实现手机号验证码功能 |超级详细,建议收藏

👨‍🎓作者:bug菌

🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。

🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系bug菌处理。

【开发云】年年都是折扣价,不用四处薅羊毛

         嗨,家人们,我是bug菌呀,我又来啦。今天我们来聊点什么咧,OK,接着为大家更《springboot零基础入门教学》系列文章吧。希望能帮助更多的初学者们快速入门!

       小伙伴们在批阅文章的过程中如果觉得文章对您有一丝丝帮助,还请别吝啬您手里的赞呀,大胆的把文章 点亮👍吧,您的点赞三连( 收藏⭐️+关注👨‍🎓+留言📃)就是对bug菌我创作道路上最好的鼓励与支持😘。时光不弃🏃🏻‍♀️,创作不停💕,加油☘️

一、前言🔥

       经过上几期的redis教学,所以现在你们应该掌握的能力有如下:

  • 能独立实现springboot框架集成redis等相关配置。
  • 能独立书写test-case并进行redis类方法实例测试。
  • 能独立进行客户端redis基本命令操作。
  • 能独立代码实现redis相关业务代码。
  • ...
有的小伙伴就问了:"bug菌你都还没讲到怎么具体结合redis实现业务逻辑呀?"
我:"哈哈哈哈哈哈,你们就不会举一反三嘛!"
我:"好好好..."

       那我再结合具体场景,带着大家如何在业务场景中结合redis来做,我就希望在我讲的过程中,你们都能认真听讲哈!

       好啦,那我要开始咯。请同学们肃静,认真听并做好笔记。

二、场景解读🔥

        结合redis实现一个手机验证码的功能。

       同时手机验证码有如下4点内容要求:大家请听清楚。

  1. 验证码长度为六位数字。
  2. 一个手机号一天只能发送三次验证码机会,超过三次拒绝发送。
  3. 要求验证码有效期为两分钟。
  4. 发送验证码间隔时间为一分钟。

三、代码实现🔥

        咱们就按上边的业务要求,一步一步来。如下是具体实现该功能的代码,仅供参考。

1️⃣获取随机获取六位数字

/**
 * 随机获取六位数字
 *
 * @return
 */
public String getCode() {
    int code = (int) ((Math.random() * 9 + 1) * 100000);
    return String.valueOf(code);
}

2️⃣获取验证码

/**
 * 获取验证码,存入redis中并设置过期时间
 */
public void verifyCode(String phone) {

    //1、定义手机号、验证码标识
    String phoneKey = phone + "_count";
    String codeKey = phone + "_code";

    //2、每个号码只能发送三次
    String count = redisMediator.get(phoneKey);

    //3、从次数进行判断
    if (count == null) {

        //说明此号码第一次申请
        //插入phone标识,并设置过期时间
        redisMediator.set(phoneKey, "1", Long.valueOf(24 * 60 * 60));
    } else if (Integer.parseInt(count) <= 2) {

        //获取当前用户验证码剩余时间
        long keyExpirationTime = redisMediator.getKeyExpirationTime(phoneKey);
        System.out.println("keyExpirationTime:" + keyExpirationTime);
        //获取当前次数
        String codeCount = redisMediator.get(phoneKey);
        //次数+1
        int newCount = Integer.parseInt(codeCount) + 1;
        redisMediator.set(phoneKey, String.valueOf(newCount), keyExpirationTime);
    } else {

        //当天3次机会用完了
        System.out.println("当天3次机会用完了!请明日再试");
        return;
    }
    //获取随机6位验证码
    String code = this.getCode();
    //验证码存入redis并设置过期时间(2min)
    redisMediator.set(codeKey, code, Long.valueOf(2 * 60));
}

3️⃣校验验证码是否正确

/**
 * 校验验证码是否有效
 */
public boolean checkCode(String phone, String code) {
    String codeKey = phone + "_code";
    String redisCode = redisMediator.get(codeKey);
    if (code.equals(redisCode)) {
        return true;
    }
    return false;
}

       其实说实话,这个逻辑很简单的,唯独就是要注意一点,就是按获取验证码次数判断,其他的都没啥。

       然后解释一下,为什么我在1<=count<=3 这一层逻辑中,有查询countKey的过期时间,对吧。为什么要多此一步呢?其实啊我这是为了避免在用户下次申请的时候,又重置过期时间,那这样,就会造成有的用户在长时间无法进行短信申请,你们想想,是不是?

       假如有的用户在据上一次申请操作很久之后又进行了第二次申请(但这是countKey还未过期),那该用户的count值进行+1,如果过期时间被重置,那么这位用户就得要再等24个小时才能再次验证码申请,对吧?这不反人类操作么。所以这点,你们也注意一下咯。

四、课后作业🔥

       不知道小伙伴们注意到没,发送手机验证码的第4点要求,我上边代码压根没有涉及到这块功能点,对吧,这点我特意留出来,就是为了给大家布置作业啦。

所以希望小伙伴能好好完成啊,很简单的,依葫芦画瓢。

简单说下我个人的思路:仅供参考

1️⃣思路一

       首先要考虑两次时间间隔为一分钟,第一种做法,就是跟你计算该用户当天获取验证码次数一样,那就把[ 手机号+固定字符串 ] 作为一个唯一间隔标识,然后在第一次获取验证码进行写入,然后过期时间就设置一分钟,随后再判断非第一次且还有获取次数的情况下先判断该间隔标识是否存在,如果存在,那就说明两次时间间隔不足一分钟,直接返回提示用户“两次获取验证码间隔时间小于一分钟,请稍后重试”,或者你想更友好的提醒用户啥时候可以再次提醒,那你就把间隔标识的过期时间查出来,然后直接拼接到提示语句上一并返回即可。如果不存在间隔标识,那说明间隔时间符合要求,直接放过。

2️⃣思路二

       因为对验证码有过期时间记录,所以你就可以借用验证码过期时间作为参照物,由于验证码过期时间time1为两分钟,而获取验证码时间time2间隔为一分钟,由于同时间维度,所以你就可以进行做差,用2min-time1 与 1min做比较,如果(2min-time1) > 1min ,说明两次间隔时间才过去(2min-time1),不足一分钟,直接返回提醒用户“两次获取验证码间隔时间小于一分钟,请稍后重试”;如果(2min-time1)<1min,那就说明间隔时间符合要求,直接放过。

       以上就是我对这个功能点的两种见解,各有各的好处吧,出发点一个在代码上,一个在redis上。不知道你们更倾向那种思路呢,或者你们有哪些更新颖的思路,可以下方评论区留言,告诉我,一起交流学习,让我知道你们的想法。

       ok,以上就是我这期的全部内容啦,如果还想学习更多,你可以看看我的往期热文推荐哦,每天积累一个奇淫小知识,日积月累下去,你一定能成为令人敬仰的大佬的。好啦,咱们下期见~

五、往期推荐🔥

六、文末🔥

        如果还想要学习更多,小伙伴们可关注bug菌专门为大家创建的专栏《springboot零基础入门教学》,从无到有,从零到一!希望能帮助到更多小伙伴们。

【开发云】年年都是折扣价,不用四处薅羊毛

       我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!

        最后送大家两句我很喜欢的话,与诸君共勉!


☘️做你想做的人,没有时间限制,只要愿意,什么时候都可以start。

🍀你能从现在开始改变,也可以一成不变,这件事,没有规矩可言,你可以活出最精彩的自己。


​​​​

💌如果文章对您有所帮助,就请留下您的吧!(#^.^#);

💝如果喜欢bug菌分享的文章,就请给bug菌点个关注吧!(๑′ᴗ‵๑)づ╭❤~;

💗如果对文章有任何疑问,还请文末留言或者加群吧;

💞鉴于个人经验有限,所有观点及技术研点,如有异议,请直接回复参与讨论(请勿发表攻击言论,谢谢);

💕版权声明:原创不易,转载请附上原文出处链接和本文声明,版权所有,盗版必究!!!谢谢。

相关文章:

  • 原始套接字
  • 【C语言刷LeetCode】1953. 你可以工作的最大周数(M)
  • 猿创征文|Python基础——Visual Studio版本——Web开发
  • 【C语言刷LeetCode】395. 至少有 K 个重复字符的最长子串(M)
  • 利用 HomeAssistant 实现电脑远程开关机
  • 练习31-35:多表关联查询、多条件自连接查询、子查询、窗口函数等
  • windows下安装protocol buffer
  • Kubernetes 调度器学习
  • Android ADB常用命令
  • 基于51单片交通灯控制器_紧急+行人+总开关
  • Java 随笔 代理模式 1-spring aop
  • Kotlin(十一)Kotlin中的Object关键字
  • java服务器端开发-servlet:2_0、Servlet执行过程介绍:get请求与post请求、编码相关等
  • 自己整理的“无培训广告”的技术公众号!
  • springboot logback-spring.xml 整合apollo实现动态配置日志级别
  • 时间复杂度分析经典问题——最大子序列和
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Android框架之Volley
  • extjs4学习之配置
  • JavaScript标准库系列——Math对象和Date对象(二)
  • MySQL QA
  • node和express搭建代理服务器(源码)
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • vue 配置sass、scss全局变量
  • vue中实现单选
  • 记录:CentOS7.2配置LNMP环境记录
  • 京东美团研发面经
  • 马上搞懂 GeoJSON
  • 排序算法学习笔记
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 硬币翻转问题,区间操作
  • postgresql行列转换函数
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​Linux·i2c驱动架构​
  • (07)Hive——窗口函数详解
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (十八)SpringBoot之发送QQ邮件
  • (四)Linux Shell编程——输入输出重定向
  • (转)IOS中获取各种文件的目录路径的方法
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .Net程序帮助文档制作
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • :中兴通讯为何成功
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • @RequestParam,@RequestBody和@PathVariable 区别
  • @RestControllerAdvice异常统一处理类失效原因
  • @synthesize和@dynamic分别有什么作用?