短信验证码的简单实现

2020-07-20 10:42:42 浏览数 (1)

序言


短信验证码是所有 APP 必不可少的基础功能模块之一,这篇文章将会简单的实现这一功能。

短信接口平台


收发短信必须要借用通信运营商的通道,而不少短信接口平台通过自身与通信运营商对接并对外提供简单高效的 API 接口为广大的软件开发者提供了更加快捷优质的服务。

对于短信接口平台,我这里将其分为两种:

第一种,验证码由软件开发者(即短信接口平台的用户)提供,短信接口平台不会保存和处理验证码,也就是说验证码的校验过程需要由开发者处理;

另一种,验证码由短信接口平台提供,同时其会提供另一个负责校验此验证码的接口,即验证码不需要由开发者处理和校验,更加省事方便。

当然,一个短信接口平台是有可能同时提供以上两种接口的,至于具体的短信接口平台公司,这里就不提了。

验证码的存储


这里主要说下上述第一种短信接口的情况,即验证码由我们自己随机生成,并且我们需要将其存储以供后续判断验证码是否正确。

对于验证码的存储又可以分为以下两种:

第一种,验证码存储在服务器端的 session 中(其实随便一个对象都可以),不需要使用数据库资源,但是一旦服务器异常重启,session 中的数据将会全部清空,也就是说验证码一段时间内将会全部失效,同时另外一个必须重视的问题是,我们一定要清除掉 session 中的过期数据,不然其将会不停地占用内存以至于造成内存泄漏的情况。

第二种,验证码存储在数据库中,这样会占用额外的数据库资源,但显然服务器端将会更加轻松,同时不少数据库提供了 TTL ( time to live )的功能,通过设置数据的有效期,数据库将会自动删除掉过期的数据,当然,我们也可以单纯的存储验证码创建或失效的时间,拿取此时间自行判断验证码是否在有效期内。

以我的性格,肯定是用数据库的 TTL ,不用多说。

实现示例


用哪个数据库呢?直接用 mongo 就得了,本身就支持 TTL ,而且项目其它数据的存储也会用 mongo ,所以没有必要为了一个验证码多搞一个 redis 数据库上去,当然如果项目本身就会用 redis 做缓存的情况除外。

服务器端的逻辑过程:

1、接受用户的手机号,进行合法性判断。

2、随机产生 4 位数字验证码。

3、调用短信接口平台的 API 接口,将随机产生的验证码和用户的手机号作为输

入参数,接收此接口的输出并判断短信验证码是否成功发送。

4、将验证码和手机号存入数据库中,并设置 TTL 即验证码的有效时间。

5、校验过程,输入手机号和验证码查询数据库中是否有对应存在的数据。

大致过程就是这样。

具体实现:

1、手机号合法性判断:复杂的,查询三大运营商的合法个人号段,这个太麻烦且实际意义不大,简单一点弄,以 1 开头的 11 位数字即可,正则判断如下图:

2、随机生成验证码:Math.random() 自己去拼接吧。

3、短信平台的接口调用:不同平台接口不同,自己去看官方文档。

4、存储验证码和手机号、设置 TTL 有效时间:

这里用的 mongoose 如下图

注意红色圈出来的部分,在 schema 中 必须定义一个 date 类型的数据,且给其加上索引并设置 expires 即有效时间,实际操作的数据 arr 必须与此 schema 对应( 我在这卡了一整天才踏过了这个坑 ),对于存储则是此手机号若有记录则更新,若没有则直接创建,所以用了 findOneAndUpdate 并且有了最后的红色圈的设置。

5、验证码校验:查询是否有手机号和验证码同时匹配的数据即可。

0 人点赞