本帖最后由 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的环境。写的比较粗糙,但主要是为了教大家流程和思路。
|