背景说明
验证码可能会用在注册、登陆、找回密码等多个功能上。
可能会使用手机验证码或者邮箱验证码等多种方式。
这里记录一下自己的验证码实现方式。
解决方案
步骤一:发送验证码
客户端调用发送验证码api
传入字段
字段 |
类型 |
描述 |
String |
邮箱 |
|
mobile |
String |
手机号 |
type |
String |
目的服务. 允许值: |
Api收到请求后
需要先检查一下发送记录,看看是否能够发送验证码:
1检查验证码最小发送间隔
2检查验证码今日已发送次数
接着进行发送记录:
1刷新最后发送时间
2递增今日发送次数
然后是存储验证码信息
结构是这样的
{
“addr”:”[email protected]”,//邮箱或手机号
“code”:”985764”,//验证码
“type”:”login”,//目的服务
“sendTime”:1509721130,//验证码发送时间戳
“activeMinute”:10//验证码有效时间
}
直接存到缓存中,根据activeMinute加上过期时间即可。
最后发送时间以及今日发送次数也都可以放在缓存中。
最后将验证码的实际发送交给队列处理。发送出去的验证码短信或者邮件,可以根据type字段,说明该验证码用于什么业务上。
步骤二:验证验证码并获取服务令牌
用户输入验证码后
客户端调用验证验证码api
传入字段
字段 |
类型 |
描述 |
addr |
String |
用户地址(邮箱或手机号). |
code |
Number |
手机验证码. |
接到调用后
后端先根据addr找到刚才验证码信息
验证验证码是否正确
如果验证码正确则生成令牌
令牌的实体
{
“addr”:”[email protected]”,//邮箱或手机号
“type”:”login”,//目的服务
“time”:1509721160,//令牌的生成时间戳,与上一步的不同
“activeMinute”:10//令牌的有效时间,与上一步的不同
}
转换成字符串后,使用密钥加密(防止用户篡改令牌,密钥不能公开),得到令牌字符串并返回给客户端。
步骤三:在具体需要验证码的业务中,验证令牌
比如在实际的注册时
调用注册api时,附加传入上一步得到的令牌
后端使用密钥解密令牌后得到,检查令牌中的地址是否就是注册时填的地址,检查令牌中的目的服务是不是就是注册服务,检查令牌是否还有效。
如果令牌有效才执行实际的注册步骤。