Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

短信验证功能

业务流程

  1. 用户点击“发送验证码”按钮,前端向后端发送请求,包含手机号信息。
  2. 后端生成一个随机验证码(如 6 位数字)和唯一标识(UUID),并将验证码和 UUID 存储到 Redis 中并设置过期时间,以手机号作为唯一 Key。
  3. 短信服务商将验证码发送到用户的手机号,同时后端通过 Redis 限制发送频率(如每分钟最多发送一次,每天最多发送 5 次)。
  4. 后端将 UUID 返回给前端,前端将 UUID 存储在本地(如 localStoragesessionStoragesessionStorage存储安全性更高)。
  5. 用户收到短信后,输入验证码,前端将手机号、验证码和 UUID 一起提交给后端。
  6. 后端使用手机号从 Redis 获取验证码记录,并校验提交的 UUID 和验证码是否匹配: - 如果匹配,则验证成功,并立即删除 Redis 中的验证码记录,执行登录流程(如生成 Token)。 - 如果不匹配,记录错误次数,超过最大错误次数后锁定手机号的验证功能一段时间。
  7. 验证成功后,返回登录成功的 Token 或其他相关信息。

解决的问题

  1. 更细化的 key 设计是这样的:verification:{类型}:{场景}:{目标}{类型}:如 sms(短信)、email(邮箱),{场景}:如 login(登录)、register(注册)。{目标}:手机号或邮箱。
  2. 除了手机号限制外,还建议对单个 IP 的请求频率进行限制,防止攻击者使用不同的手机号进行短信轰炸。
  3. 在后端对验证码发送频率做了限制,不会出现因为网络波动等原因导致用户同时收到多个验证码。
    UUID 的作用:防止验证码泄露被滥用。如果攻击者通过某种方式窃取了验证码(例如短信被拦截或用户截图泄露),那么直接用手机号+验证码可以绕过验证。使用 UUID 作为额外的校验参数,可以增加破解难度,因为攻击者需要同时知道验证码和 UUID 才能通过验证

前端的一些验证工作

  1. 按钮置灰:防止用户重复点击,减少无效请求。
  2. 验证码前置:填写验证码之后才可以发送短信。
  3. 手机号合法性校验:提前校验手机号格式,避免无效请求浪费后端资源。
  4. HTTPS 加密传输:通过 HTTPS 加密传输,避免验证码和 UUID 泄露。

评论