Redis 在短信验证码与用户登录中的应用
Redis 在登录功能中主要有两个作用:
存储短信验证码:用于验证用户身份。
存储用户登录态:通过 Token 识别已登录用户。
一、短信验证码存储
短信验证码适合使用 Redis 的 String 数据类型。
例如:
Key: sms:login:13800138000
Value: 123456
TTL: 300秒Spring Boot 示例:
stringRedisTemplate.opsForValue().set(
"sms:login:" + phone,
code,
5,
TimeUnit.MINUTES
);注意事项:
验证码必须设置过期时间,通常为 5 分钟。
验证成功后应删除验证码,防止重复使用。
限制验证码发送频率和验证失败次数,防止恶意刷接口。
高并发场景下,验证码校验与删除需要考虑原子性,防止重复验证成功。
二、用户登录流程
以手机号验证码登录为例:
1. 用户输入手机号
↓
2. 服务端生成验证码
↓
3. 将验证码存入 Redis,并设置过期时间
↓
4. 通过短信服务发送验证码
↓
5. 用户输入验证码
↓
6. 服务端从 Redis 获取验证码并校验
↓
7. 校验成功,生成 Token
↓
8. 将 Token 对应的用户信息存入 Redis
↓
9. 返回 Token 给前端
↓
10. 前端后续请求携带 Token
↓
11. 服务端通过 Token 查询 Redis,验证登录状态登录态存储示例:
Key: login:token:abc123
Value: {"userId":1001,"username":"admin"}
TTL: 7200秒这里的 Token 应使用安全随机值生成,不能直接使用用户 ID 或手机号。
用户退出登录时,可以删除 Redis 中对应的登录态,实现 Token 失效。
三、登录信息使用 String 还是 Hash?
Redis 的 String 和 Hash 都可以存储用户登录信息。
1. String 类型
将用户对象序列化为 JSON,再存储到 Redis。
Key: login:token:abc123
Value:
{
"userId": 1001,
"username": "admin",
"nickname": "张三"
}优点:
实现简单,方便序列化和反序列化。
适合整个对象一起读取的场景。
缺点:
无法直接修改 JSON 内的某个属性。
修改单个字段时,通常需要读取整个 JSON、修改后重新写入。
注意:更新 String 不需要先删除旧值,直接使用 SET 覆盖即可。
2. Hash 类型
Hash 可以将用户对象的属性分别存储。
Key: login:token:abc123
Field Value
------------------
userId 1001
username admin
nickname 张三优点:
支持单独读取和修改某个字段。
不需要每次更新整个对象。
对于字段较少、数据较小的 Hash,Redis 可以采用紧凑编码节省内存。
缺点:
对象字段与 Hash 字段需要进行映射。
如果经常读取整个对象,不一定比 String 更方便。
需要特别注意:
Hash 不一定比 String 更节省内存。 具体取决于字段数量、数据大小及 Redis 的内部编码方式。
另外,Hash 的过期时间通常设置在整个 Key 上,而不是每个字段上。
四、实际开发怎么选?
对于常见的 Spring Boot 项目:
推荐使用 StringRedisTemplate + JSON 存储登录用户信息。
这种方式实现简单、可读性好,也方便跨语言使用。
如果业务确实存在频繁修改单个字段的需求,再考虑使用 Hash。
五、总结
Redis 在登录系统中主要解决两个问题:
验证码校验:利用 String 和 TTL,实现验证码的临时存储。
登录状态管理:利用 Token 关联用户信息,实现登录验证、过期和退出登录。
需要重点掌握:
验证码与登录态为什么都需要设置 TTL。
Token 如何与 Redis 中的用户信息关联。
String 和 Hash 的区别及适用场景。
验证码防刷、重复使用与并发校验问题。
一句话总结:验证码使用 String,登录态默认使用 String + JSON,需要频繁修改独立字段时再考虑 Hash。
