如何使用 Redis 缓存验证码
目录
🧠 Redis 缓存验证码的工作原理
🧰 实现流程
1. 安装 Redis 和 Python 客户端
2. 生成并缓存验证码
示例代码:生成并存储验证码
3. 发送验证码(以短信为例)
4. 校验验证码
示例代码:校验验证码
🔑 防刷策略与扩展
🌍 高级扩展
使用 Redis 缓存验证码是一个高效的防刷和防作弊的策略,它可以保证验证码在短时间内有效,并且防止重复提交或暴力破解。Redis 的高性能和过期时间机制使其非常适合用于验证码的存储和管理。
🧠 Redis 缓存验证码的工作原理
-
生成验证码:通常是一个随机的数字或字符串(如 6 位数字验证码
123456
)。 -
存储验证码:将生成的验证码存储到 Redis 中,并设置过期时间。
-
发送验证码:通过短信、邮件、WebSocket 等方式发送给用户。
-
校验验证码:用户输入验证码后,后端查询 Redis 存储的验证码并进行校验。如果验证码正确且未过期,验证通过。
-
清除过期验证码:Redis 会在验证码过期后自动删除缓存的验证码。
🧰 实现流程
1. 安装 Redis 和 Python 客户端
首先,确保已经安装了 Redis 服务,并且在本地或者云端运行。然后安装 Redis 的 Python 客户端:
pip install redis
2. 生成并缓存验证码
我们可以生成一个随机的 6 位数字验证码,并将其存入 Redis,设置过期时间为 5 分钟(300 秒)。
示例代码:生成并存储验证码
import random
import redis# 连接本地 Redis
r = redis.Redis(host='localhost', port=6379, db=0)# 生成 6 位随机验证码
def generate_code():return str(random.randint(100000, 999999))# 存储验证码到 Redis(设置过期时间为300秒)
def store_code(phone, code):key = f"code:{phone}" # 使用手机号作为 Redis keyr.setex(key, 300, code) # 300秒后自动过期# 测试:存储验证码并打印
phone = '13812345678'
code = generate_code()
store_code(phone, code)
print(f"存储验证码:{code},有效期:5分钟")
在这个例子中,我们生成了一个 6 位随机数字作为验证码,并将其存储在 Redis 中,使用手机号 phone
作为键(code:{phone}
)。然后,我们设置了验证码在 300 秒(5 分钟)后过期。
3. 发送验证码(以短信为例)
发送验证码的具体操作取决于你使用的服务。例如,假设你使用腾讯云短信 API 发送验证码,可以按照以下步骤进行:
# 使用腾讯云短信 API 发送验证码的简单示例
from tencentcloud.sms.v20210111 import sms_client, models
from tencentcloud.common import credentialdef send_sms(phone, code):cred = credential.Credential("你的SecretId", "你的SecretKey")client = sms_client.SmsClient(cred, "ap-guangzhou")req = models.SendSmsRequest()req.SmsSdkAppId = "1400XXXXXXX"req.SignName = "你的短信签名"req.TemplateId = "123456" # 验证码模板IDreq.TemplateParamSet = [code]req.PhoneNumberSet = [f"+86{phone}"]client.SendSms(req)# 发送验证码
send_sms(phone, code)
发送的验证码会存储在 Redis 中,用户通过短信获取验证码。
4. 校验验证码
当用户输入验证码后,你需要从 Redis 中取出该手机号的验证码进行验证。如果验证成功,则进行后续操作(如登录、注册等)。
示例代码:校验验证码
# 校验验证码
def verify_code(phone, user_input):key = f"code:{phone}"real_code = r.get(key) # 从 Redis 获取验证码if not real_code:return "验证码过期"if user_input != real_code.decode():return "验证码错误"# 验证成功,删除验证码r.delete(key) # 验证通过后删除验证码,防止再次使用return "验证通过"# 假设用户输入的验证码
user_input = '123456'
result = verify_code(phone, user_input)
print(result)
在这个代码中,我们首先从 Redis 获取存储的验证码,并与用户输入的验证码进行比对。如果匹配,则验证成功,之后我们删除 Redis 中的验证码,防止重复使用。
🔑 防刷策略与扩展
-
频率限制:同一个手机号或 IP 在短时间内不要频繁获取验证码。例如可以限制每个手机号 1 分钟内最多请求 1 次验证码。
-
验证码过期时间:验证码应该在较短时间内过期,避免用户重复使用过期的验证码。通常设置 5 分钟为有效期。
-
验证码存储方式:使用 Redis 的
setex
方法(设置过期时间)是最常见的方式,因为 Redis 会在过期后自动删除数据,减少了后台清理的工作。 -
添加验证码限制:为防止恶意刷验证码,可以在 Redis 中记录请求次数,超过一定次数后需要加入图形验证码,或者暂停请求。
-
Redis 集群支持:如果是大规模的系统,单个 Redis 实例可能不足以处理请求流量,可以考虑使用 Redis Cluster。
🌍 高级扩展
-
验证码带图片(图形验证码):结合 Redis 可以存储图形验证码的哈希值,确保图形验证码的有效性;
-
验证码冷却时间:例如,对于同一个手机号,如果短时间内请求了过多验证码,可以暂时阻止请求,防止滥用。
-
短信与图形验证码结合:对于频繁访问的接口,可以结合图形验证码与短信验证码,避免恶意刷接口。
-
多平台支持:通过短信、邮箱等方式发送验证码,可以将 Redis 存储的验证码同时与多个平台同步。