A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 neekin 于 2018-1-11 13:27 编辑

随着手机的普及,人手一部的手机的情况下,在使用互联网服务时需要手机接收验证码的场景是越来越多了。
其实技术点非常简单,主要是在服务端。 下面我列出一下步骤
  • 浏览器或者客户端发送手机号到服务端
  • 服务端先根据模板生成短信文本(包含验证码)发送给短信服务商
  • 服务端将生成的验证码以及手机号码对应的存储起来
  • 客户端根据接收到的短信输入验证码并再次发送到服务端
  • 服务端验证对比
步骤大体就是这样,但其中每个步骤根据不同的技术选型都有可能不同,比如第2个步骤里面的,不同短信服务商就有不同的操作。再比如第3个步骤的,你可以把验证信息存储到数据库、或者seesion里面等等。。。
下面我将以代码实例来模拟这个过程。 为了快速演示,我用了express框架,后面我会放出完整的代码,现在看看代码片段
[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html>

<head>
  <title>
    手机验证码测试
  </title>
  <link rel='stylesheet' href='/stylesheets/style.css' />
</head>

<body>

  <input type="phone" id='phoneNum'>
  <input type="button" value='获取验证码' id='getVerificationCode'>
  <br>
  <input type="text" id='verificationCode'>
  <input type="button" value='验证' id='verify'>
  <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.js"></script>
  <script>
    $('#getVerificationCode').click(function () {
      var phone = $('#phoneNum').val();
      $.ajax({
        url: '/getverificationcode',
        data: { phone: phone },
        success: function (data) {
          alert(data);
        },
        type: "POST"

      })
    });
    $('#verify').click(function () {
      var phone = $('#phoneNum').val();
      var code = $('#verificationCode').val();
      $.ajax({
        url: '/verify',
        data: { phone: phone, code: code },
        success: function (data) {
          alert(data);
        },
        type: "POST"

      })
    });
  </script>
</body>

</html>

后台部分
[JavaScript] 纯文本查看 复制代码
var express = require('express');
var router = express.Router();
var SMS = require('../sms');

/* 打开首页 */
router.get('/', function (req, res, next) {

  res.render('index', { title: 'Express' });
});

/* 请求发送验证码*/
router.post('/getverificationcode', (req, res, next) => {
  var code = "";
  //生成验证码
  for (var i = 0; i < 4; i++) {
    code += Math.floor(Math.random() * 10)
  }

  //将手机号码和验证码放进session
  req.session['code'] = code;
  req.session['phone'] = req.body.phone;
  //这一步是关键,现在我仅仅是通过返回值的形式告诉用户的验证码,但是可以换成短信的形式来告诉用户,就可以在这里操作的。
  SMS.send(req.body.phone, code,function(data){
        res.end(data.msg)
  });
})

/* 校验验证码*/
router.post('/verify', (req, res, next) => {
  //获取用户传过来的手机号码和code
  var phone = req.body.phone;
  var code = req.body.code;
  //比对手机号码和验证码 
  if (phone == req.session['phone'] && code == req.session['code']) {
    //比对成功后删除以免多次验证
    delete req.session.phone;
    delete req.session.code;
    res.end('验证成功')
  }
  res.end('验证失败')
})

module.exports = router;
这就形成了一个验证码的过程,后面,我们需要接入短信服务商。
首先不管任何短信服务商,他们都是提供接口给我们,而我需要做的,就是调用他们的接口,传递我们的参数,然后他们去发送短信。
但不能谁都能调用他们的接口,调用他们的接口第一步就是获取一个秘钥,相当于开门的门钥匙。想想也是正常的,毕竟一条短信也是需要成本的,如果没有一定限制,别人很容易调用,会造成一定的资源浪费。
我们先看看要使用的短信服务商,云片网,注册网之后,我们会获取到一个叫APIKEY的东西

这个很重要,我们先记下来。

云片网提供了很多接口,我们打开他们的文档看一看


虽然参数很多,但是需要我们用的,其实只要三个参数。
apikey,需要接收的手机号码mobile,还有要发送的文本text,
他有一个代码示例,参考他们的代码示例,我们把后台代码稍微修改一下
[JavaScript] 纯文本查看 复制代码
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/getverificationcode', (req, res, next) => {
  var code = "";
  //生成验证码
  for (var i = 0; i < 4; i++) {
    code += Math.floor(Math.random() * 10)
  }
  //将手机号码和验证码放进session,如果愿意,也可以设置一下过期时间等。
  req.session['code'] = code;
  req.session['phone'] = req.body.phone;
   //准备参数
    var text = `【传智NeeKin】亲爱的${name},您的验证码是${code}。有效期为10分钟,请尽快验证`
    var content = querystring.stringify({
            apikey: 'xxxxxxxxxxxxxxxxxxxxxx',
            mobile: req.body.phone,
            text: text
        });
    //给请求接口的客户端准备参数
    var option = {
            host: 'sms.yunpian.com',
            path: '/v2/sms/single_send.json',
            method: 'POST',
            headers: {
                "Content-Length": Buffer.byteLength(content),
            }
        } 
    //加载http模块去请求接口并且打印一下请求结果
    var req2 = http.request(option, function (res2) {
        console.log("statusCode: ", res2.statusCode);
        console.log("headers: ", res2.headers);
        var _data = '';
        res2.on('data', function (chunk) {
                _data += chunk;
        });
        res2.on('end', function () {
                console.log("\n--->>\nresult:", _data)
            });
    });

    req2.write(content);
    req2.end();
  res.end('获取验证码OK');
})

虽然这样是已经达到目的了,但是这样写的比较死,不太符合编程习惯,所以我们进行一个小小的封装

[JavaScript] 纯文本查看 复制代码
var SMS = {
        send: function (mobile, code,cb) {
        var text = `【传智NeeKin】亲爱的${mobile},您的验证码是${code}。有效期为10分钟,请尽快验证`
        var content = querystring.stringify({
            apikey: 'xxxxxxxxxxxxxxxxxxxxxx',
            mobile: mobile,
            text: text
        });
     
        var option = {
            host: 'sms.yunpian.com',
            path: '/v2/sms/single_send.json',
            method: 'POST',
            headers: {
                "Content-Length": Buffer.byteLength(content),
            }
        }
       

        var req = http.request(option, function (res) {
            var _data = '';
            res.on('data', function (chunk) {
                _data += chunk;
            });
            res.on('end', function () {
                cb(_data);
            });
        });

        req.write(content);
        req.end();
    }
}

发送成功后,云片会返回一个结果给我们

[JavaScript] 纯文本查看 复制代码
{
    "code": 0,
    "msg": "发送成功",
    "count": 1,
    "fee": 0.05,
    "unit": "RMB",
    "mobile": "13200000000",
    "sid": 3310228982
}

后台只需要调用一下就行了
[JavaScript] 纯文本查看 复制代码
  req.session['phone'] = req.body.phone;
  SMS.send(req.body.phone, code,function(data){
        res.end(data.msg)
  });

这个就是一个短信验证码的完整流程了,如果要求比较多,比如过期时间希望更久一点,可以放进数据库里面,如果速度要求快,可以使用redis等内存数据库,等等……附件有完整的代码,要运行请确保有node.js的环境。写的比较粗糙,但主要是为了教大家流程和思路。


sendSMS.zip

803.82 KB, 阅读权限: 10, 下载次数: 2

评分

参与人数 1黑马币 +1 收起 理由
huchen + 1 很给力!

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马