Springboot系列(十四):集成redis,代码实现手机号验证码功能(Redis零基础教学-实战篇)

779 阅读4分钟

👨‍🎓作者:bug菌
✏️博客:CSDN掘金infoQ51CTO
🎉简介:CSDN博客专家,C站历届博客之星Top50,掘金/InfoQ/51CTO等社区优质创作者,全网合计8w粉+,对一切技术感兴趣,重心偏Java方向;硬核公众号「 猿圈奇妙屋」,欢迎小伙伴们的加入,一起秃头,一起变强。
..
✍️温馨提醒:本文字数:1999字, 阅读完需:约 5 分钟

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

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

一、前言🔥

环境说明:Windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE

经过上几期的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点要求,我上边代码压根没有涉及到这块功能点,对吧,这点我特意留出来,就是为了给大家布置作业啦。

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

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

思路一:

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

思路二:

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

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

... ...

       OK,以上就是这期所有的内容啦,如果有任何问题欢迎评论区批评指正,咱们下期见。

五、往期热门推荐

文末🔥

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

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

感谢认真读完我博客的铁子萌,在这里呢送给大家一句话,不管你是在职还是在读,绝对终身受用。
时刻警醒自己:
抱怨没有用,一切靠自己;
想要过更好的生活,那就要逼着自己变的更强,生活加油!!!