手机验证码缓存的实现

2025-10-01 01:04:25 4阅读

验证码缓存实现

1. 验证码存储

Key: sms:validate:code:{phone}

Value: 验证码数字

过期时间: 默认5分钟(可配置)

2. 发送频率限制

Key: sms:validate:phone:{phone}

Value: 1(占位符)

过期时间: 60秒

核心代码实现

发送验证码

在SmsServiceImpl.sendSms方法中:

// 生成6位随机验证码
Integer code = CrmebUtil.randomCount(111111, 999999);
// 将验证码存入redis,过期时间默认5分钟
redisUtil.set(userService.getValidateCodeRedisKey(phone), code, Long.valueOf(codeExpireStr), TimeUnit.MINUTES);
// 设置发送频率限制,60秒内不能重复发送
redisUtil.set(SmsConstants.SMS_VALIDATE_PHONE_NUM + phone, 1, 60L);

其中

userService.getValidateCodeRedisKey(phone)方法返回完整的key

public String getValidateCodeRedisKey(String phone) {
return SmsConstants.SMS_VALIDATE_PHONE + phone;
}

验证验证码

UserCenterServiceImpl.checkValidateCode方法中:

private void checkValidateCode(String phone, String code) {
Object validateCode = redisUtil.get(SmsConstants.SMS_VALIDATE_PHONE + phone);
if (validateCode == null) {
throw new CrmebException("验证码已过期");
}
if (!validateCode.toString().equals(code)) {
throw new CrmebException("验证码错误");
}
// 验证成功后删除验证码
redisUtil.delete(SmsConstants.SMS_VALIDATE_PHONE + phone);
}

频率限制检查

在发送验证码前会检查发送频率:

if (redisUtil.exists(SmsConstants.SMS_VALIDATE_PHONE_NUM + phone)) {
    throw new CrmebException("您的短信发送过于频繁,请稍后再试");
}

这种设计确保了:

验证码在一定时间内有效(默认5分钟)

防止短信轰炸(60秒内只能发送一次)

验证码一次性使用(验证成功后立即删除)

防重复发送短信验证码机制

在CRMEB系统中,通过Redis实现了一个简单的频率限制机制,防止用户在60秒内重复发送短信验证码。

实现原理

这个机制的核心在于使用Redis的过期时间(TTL)特性:

// 设置发送频率限制,60秒内不能重复发送
redisUtil.set(SmsConstants.SMS_VALIDATE_PHONE_NUM + phone, 1, 60L);

这行代码的作用是:

以键 sms:validate:phone:{phone} 在Redis中存储一个值为1的数据

设置该键的过期时间为60秒

检查机制

在发送短信验证码前,系统会检查该键是否存在:

if (redisUtil.exists(SmsConstants.SMS_VALIDATE_PHONE_NUM + phone)) {
throw new CrmebException("您的短信发送过于频繁,请稍后再试");
}

工作流程

用户请求发送验证码

系统检查Redis中是否存在 sms:validate:phone:{phone} 键

如果存在,说明60秒内已发送过验证码,抛出异常

如果不存在,继续执行发送验证码流程

发送验证码成功后,设置 sms:validate:phone:{phone} 键,有效期60秒

为什么能实现60秒限制

Redis的过期机制会自动在60秒后删除这个键,所以:

在60秒内,键存在,系统拒绝发送新的验证码

60秒后,键自动过期并被删除,下次请求时检查发现键不存在,允许发送验证码

这是一种简单而有效的方式,利用了Redis的自动过期特性来实现时间窗口内的频率控制。

免责声明:由于无法甄别是否为投稿用户创作以及文章的准确性,本站尊重并保护知识产权,根据《信息网络传播权保护条例》,如我们转载的作品侵犯了您的权利,请您通知我们,请将本侵权页面网址发送邮件到qingge@88.com,深感抱歉,我们会做删除处理。