目录
概述
本次笔记要记录的是短信验证码登录功能的实现,使用lua
脚本简化验证登录的流程,以及使用阿里云短信服务实现真实的发送短信验证码登录的功能。
短信验证码登录
概述
使用短信验证码是常见的登录功能,对于用户来说使用短信验证码登录的流程一般是在网站输入手机号,点击获取验证码,输入验证码通过验证后登录成功。对于后端服务来说有几件事要注意的,首先是收到用户获取验证码的请求时记录次数,在一段时间内限制请求次数(如10分钟内5次请求);然后是验证验证码的流程,发送短信后将用户手机号和验证码存储起来并设置过期时间(如5分钟内有效);最后是当验证通过后需要将验证码删除或设置过期,若用户该手机号未注册则自动注册。
思路
对于用户来说,短信验证码登录的流程一般是这样的:用户在登录界面输入手机号点击获取验证码,用户收到短信后输入验证码,若验证码正确则登录成功,若手机号未注册则自动注册(一般都有自动注册协议让用户勾选)。
对于后台服务来说,短信验证码的发送登录的流程一般是这样的:后台服务收到发送验证码的请求,查询该手机号是否还有发送短信的剩余次数,若可以发送则生成随机数调用SMS服务发送验证码,同时记录该手机号在某个时间范围内的请求次数,存储该用户的手机号和验证码。
验证验证码的流程一般是这样的:
当后端服务收到验证验证码登录请求时,在刚才存储的数据中验证验证码是否正确。如果验证码正确,用户手机号未注册则给用户自动注册。若验证码错误或过期则返回登录失败。
在本次学习笔记中后端接收到发送验证码的请求时会生成6位的随机数,并将手机发送短信剩余次数和手机号及对应验证码保存到redis
数据库中。这次我们将用户请求次数限制在每10分钟5次发送验证码请求,每次请求都在redis
数据库中将该手机号的剩余发送此处减1
,如果10分钟内超过5次请求则将剩余次数置为-1
,不发送短信;将用户的验证码过期时间设置在5分钟,验证码在验证通过后要被删除(验证码只能用一次),验证码过期后在redis
中自动删除。当使用验证码通过校验后查询数据库中的用户,若用户未注册则给用户自动注册,通过用户id
生成jwt token
返回给前端。
步骤
发送验证码的请求
在controller
层我们需要做三件事,一是查询用户发送短信的剩余次数,二是调用发送验证码的方法,最后将验证码存储起来。
// 在controller层
// 请求发送验证码
func HandlerSendSMSForLogin(ctx *gin.Context) {
var fo *models.SMS
if err := ctx.ShouldBindJSON(&fo); err != nil {
zap.L().Error("Sign In with invalid params", zap.Error(err))
ctx.JSON(http.StatusBadRequest, gin.H{
"code": 400,
"msg": "bad request",
})
return
}
// 检查该用户发送短信的剩余次数
status, err := cache.CheckSMSResidualDegree(fo.Phone)
if err != nil {
log.Println("检查短信错误", err)
return
}
if status != true {
log.Println("发送短信验证码次数用完")
ctx.JSON(http.StatusTooManyRequests, gin.H{
"code": http.StatusTooManyRequests,
"msg": "操作过于频繁,请稍后再试",
})
return
}