Redis如何实现验证码发送 以及限制每日发送次数


Posted in Redis onApril 18, 2022

1、功能

  • 输入手机号,点击发送后随机生成六位数字码,2分钟有效
  • 输入验证码,点击验证,返回成功或失败
  • 每个手机号每天只能输3次

2、分析

  • 每个手机每天只能输3次:incr每次发送之后+1,当值为3时提示不能发送,过期时间为当天结束
  • 随机生成6位数字验证码:RandomUtil(hutool)
  • 验证码2分钟有效:放入redis里并设置过期时间2分钟
  • 判断验证码是否一致:从redis里获取验证码和输入的验证码进行比对

3、实现

package cn.ken.blog.controller.common;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.ken.blog.common.constant.Constants;
import cn.ken.blog.common.domain.Result;
import cn.ken.blog.common.enums.ErrorCodeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 验证码控制器
 * @author Ken-Chy129
 * @date 2022/4/17 20:28
 */
@RestController
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public class CaptureController {
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    // 生成验证码
    @GetMapping("getNumCode")
    public Result<String> getNumCode(String phone) {
        String captureLimitKey = Constants.CAPTCHA_LIMIT_KEY + phone;
        Integer counts = (Integer) redisTemplate.opsForValue().get(captureLimitKey);
        if (ObjectUtils.isEmpty(counts)) {
            // 今天第一次验证,故之前缓存中无该键
            // 距离今天结束剩下多少毫秒
            long expire = DateUtil.endOfDay(new Date()).between(new Date(), DateUnit.MS);
            redisTemplate.opsForValue().set(captureLimitKey, 1, expire, TimeUnit.MILLISECONDS);
        } else if (counts < 3) {
            // 没有超过限制次数
            redisTemplate.opsForValue().increment(captureLimitKey);
        } else {
            // 超过限制次数,不生成验证码,直接返回
            return new Result<String>().error(ErrorCodeEnum.OVER_LIMITS);
        }
        // 生成验证码
        String code = RandomUtil.randomNumbers(6); // 随机生成六位数
        String captureCodeKey = Constants.CAPTCHA_CODE_KEY + phone;
        redisTemplate.opsForValue().set(captureCodeKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        return new Result<String>().success(captureCodeKey + ":" + code);
    }
    
    // 验证验证码
    @GetMapping("verify")
    public Result<String> verify(String phone, String code) {
        String captureCodeKey = Constants.CAPTCHA_CODE_KEY + phone;
        String realCode = (String) redisTemplate.opsForValue().get(captureCodeKey);
        if (ObjectUtils.isEmpty(realCode)) {
            // redis中不存在该用户生成的验证码,证明验证码以过期销毁
            return new Result<String>().error(ErrorCodeEnum.OVERDUE_CODE);
        }
        if (realCode.equals(code)) {
            return new Result<String>().success("验证成功");
        } else {
            return new Result<String>().error(ErrorCodeEnum.ERROR_CODE);
        }
    }
    
//    @Scheduled(cron = "0 0 12 * * ?")
//    private void clear() {
//        redisTemplate.delete()
//    }
}
// Constants类

/**
 * 验证码 redis key
 */
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";

/**
 * 每日限制 redis key
 */
public static final String CAPTCHA_LIMIT_KEY = "captcha_limits:";
/**
 * 验证码有效期(分钟)
 */
public static final Integer CAPTCHA_EXPIRATION = 2;

到此这篇关于Redis实现验证码发送并限制每日发送次数的示例代码的文章就介绍到这了!

Redis 相关文章推荐
Redis 配置文件重要属性的具体使用
May 20 Redis
redis实现排行榜功能
May 24 Redis
Redis集群的关闭与重启操作
Jul 07 Redis
Redis性能监控的实现
Jul 09 Redis
基于Redis的List实现特价商品列表功能
Aug 30 Redis
浅谈Redis的keys命令到底有多慢
Oct 05 Redis
redis缓存存储Session原理机制
Nov 20 Redis
在Centos 8.0中安装Redis服务器的教程详解
Mar 21 Redis
Redis实现分布式锁的五种方法详解
Jun 14 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
redis lua限流算法实现示例
Jul 15 Redis
Redis实战高并发之扣减库存项目
Redis中key的过期删除策略和内存淘汰机制
解决 Redis 秒杀超卖场景的高并发
redis 解决库存并发问题实现数量控制
Redis超详细讲解高可用主从复制基础与哨兵模式方案
redis复制有可能碰到的问题汇总
Apr 03 #Redis
 Redis 串行生成顺序编码的方法实现
You might like
基于mysql的bbs设计(二)
2006/10/09 PHP
php中导出数据到excel时数字变为科学计数的解决方法
2013/02/03 PHP
页面版文本框智能提示JS代码
2009/11/20 Javascript
javascript 得到变量类型的函数
2010/05/19 Javascript
jQuery实现id模糊查询的小例子
2013/03/19 Javascript
js动态调用css属性的小规律及实例说明
2013/12/28 Javascript
jQuery实现的输入框选择时间插件用法实例
2015/02/28 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
JS操作xml对象转换为Json对象示例
2017/03/25 Javascript
Bootstrap模态框插件使用详解
2017/05/11 Javascript
让nodeJS支持ES6的词法----babel的安装和使用方法
2017/07/31 NodeJs
解决使用Vue.js显示数据的时,页面闪现原始代码的问题
2018/02/11 Javascript
新版vue-cli模板下本地开发环境使用node服务器跨域的方法
2018/04/03 Javascript
用JS实现根据当前时间随机生成流水号或者订单号
2018/05/31 Javascript
微信小程序基于canvas渐变实现的彩虹效果示例
2019/05/03 Javascript
JavaScript定时器使用方法详解
2020/03/26 Javascript
Python的一些用法分享
2012/10/07 Python
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
python+django+sql学生信息管理后台开发
2018/01/11 Python
Jupyter中直接显示Matplotlib的图形方法
2018/05/24 Python
Python使用re模块正则提取字符串中括号内的内容示例
2018/06/01 Python
Python实现12306火车票抢票系统
2019/07/04 Python
WxPython实现无边框界面
2019/11/18 Python
Python使用进程Process模块管理资源
2020/03/05 Python
Python 制作查询商品历史价格的小工具
2020/10/20 Python
关于python中导入文件到list的问题
2020/10/31 Python
html5 Canvas绘制线条 closePath()实例代码
2012/05/10 HTML / CSS
文言文形式的学生求职信
2013/12/03 职场文书
卫生巾广告词
2014/03/18 职场文书
生日主持词
2014/03/20 职场文书
物资采购方案
2014/06/12 职场文书
无房证明范本
2014/09/17 职场文书
中学生旷课检讨书2篇
2014/10/09 职场文书
2015高考寄语集锦
2015/02/27 职场文书
新闻简讯格式及范文
2015/07/22 职场文书
Nginx开启Brotli压缩算法实现过程详解
2021/03/31 Servers