Redis怎么实现验证码发送并限制每日发送次数

1、功能
  • 输入手机号,点击发送后随机生成六位数字码,2分钟有效

  • 输入验证码,点击验证,返回成功或失败

  • 每个手机号每天只能输3次

2、分析
  • Redis实现验证码发送并限制每日发送次数

    每个手机每天只能输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实现验证码发送,并限制每日发送次数。
1. 注册Redis
要使用Redis,需要先在官网上进行注册并下载安装包。在安装完成后,使用终端连接到Redis,并在Redis CLI中设置密码和端口号。
2. 实现验证码发送
发送验证码是一个简单的过程。可以通过开发自己的API来实现。在发送验证码之前,需要确保已连接到Redis,并使用SET命令将验证码存储在Redis中。
3. 设定过期时间
验证码必须在验证之前失效,以确保安全。过期时间可以使用Redis自带的EXPIRE命令来设置。
4. 设置每日发送次数
为了防止滥用,需要限制每个用户每日发送验证码的次数。可以用Redis的INCRBY命令实现。
5. 链接到SMTP服务器
发送电子邮件验证码需要配置SMTP服务器,以便邮件可以发送。可以使用Python的smtplib包将验证码发送到用户邮箱中。
6. 返回结果
保持API返回结果是可预测的,例如:已成功发送、今日发送次数已达上限等。
7. 测试API
成功测试API后,您的应用程序现在应该可以向Redis发送验证码并限制每个用户每日发送验证码的数量。对验证码发送的限制确保了应用程序的安全性。
通过使用Redis可以更加优化验证码的发送过程,不仅可以提高发送验证码的速度,还可以确保数据和用户安全。在当今应用程序安全方面越来越重要的时代,代码的保护和用户隐私不容忽视。