截止2021年10月28日,本文方法所用的npm包仍可下载并使用
一、集成短信服务基本步骤
- 开通阿里云账户
- 开通短信服务(100条/有效期三月免费)
- 在阿里云短信服务控制台申请 AccessKeyId 以及 secretAccessKey
- 在阿里云短信服务控制台申请短信签名与短信模板,以及内置变量
- 在阿里云短信服务测试平台测试是否可行
- 按照阿里 API 集成到自己的 Express 后端代码中 步骤中的前五步在阿里云的教程里都写的十分清楚,都是点点按钮就可以完成的交互式操作。所以本文重点介绍第六步
二、在 Express 中如何集成
阿里云官方提供了几种主流后端语言(Java,PHP,C++,TS,Python)的示例。但是注释不清晰,流程不完整。在看的时候经常产生疑惑。 所以我把自己集成到 Express 的方案记录一下。
Express基本思路
- 写一个 getCode 的路由模块,在前端发送获取验证码的请求时调用
- 获取验证码的代码 只需写在 getCode 这个路由文件中就可以了
- 在 getCode 中如何导入阿里云的库并使用(本文重点)
短信服务如何工作
- 短信验证码其实是需要你自己写的,可以是一个你自己的 getCode 文件中的一个函数,阿里云短信服务只负责帮你把这个验证码发送给用户。 例如我的验证码生成函数:
let str = "";
for (let i = 0; i < 6; i++) {
str += parseInt(Math.random() * 10);
}
return str;
}
- 阿里云发送短信的唯一条件:用户手机号
- 首先导入如下的库(与阿里云推荐的库不一样,主要是因为看不懂他的文档,但这个可以使用,并且方便配置,所以就使用它了)
const SMSClient = require("@alicloud/sms-sdk");
- 在后端的 getCode 中,开始初始化短信服务并调用。 初始化配置,此处分别传入你在阿里云申请的 AccessKeyId,secretAccessKey
let smsClient = new SMSClient({
accessKeyId: "L***************",
secretAccessKey: "j*************",
});
生成随机验证码
let str = getCode();
获取手机号并调用(其中phoneNum变量是我从 POST 请求中取出的用户手机号)。请注意TemplateParam 是你在自己的短信模板中声明的变量,我自己声明的是 Code ,可以根据你的设置进行调整
smsClient
.sendSMS({
PhoneNumbers: phoneNum,
SignName: "****", //阿里云申请的短信签名
TemplateCode: "SMS_******", //阿里云申请的短信模板
TemplateParam: `{"code":'${str}'}`, // 短信模板变量对应的实际值,JSON格式
})
.then((result) => {
let { Code } = result; //result是阿里云返回的信息,你可以自行打印查看
if (Code == "OK") {
let r = formatResponse(1, str); //这是我自己的返回数据格式化函数。可以忽略
res.send(r);
console.log(result);
}
})
.catch((err) => {
let r = formatResponse(0, "发送失败");
console.log(err);
res.send(r);
});
这样整个发送验证码的服务就完成了,你只需要去前端配置发送验证码的按钮,并携带上用户手机号发送POST请求就可以了。 最后附上自己 getCode 的全部代码结构,方便了解大致结构
var express = require("express");
var router = express.Router();
const SMSClient = require("@alicloud/sms-sdk");
const { formatResponse } = require("../response");
function getCode() {
let str = "";
for (let i = 0; i < 6; i++) {
str += parseInt(Math.random() * 10);
}
return str;
}
router.post("/", function (req, res, next) {
let str = getCode();
console.log(str);
let phoneNum = req.body.phone; //获取前端参数phone
console.log(req.body);
// phoneNum = 131*******; //获取前端参数phone
// 初始化sms_client;
let smsClient = new SMSClient({
accessKeyId: "L**********",
secretAccessKey: "j***********",
});
smsClient
.sendSMS({
PhoneNumbers: phoneNum,
SignName: "********", //签名名称 前面提到要准备的
TemplateCode: "SMS_******", / /模版CODE 前面提到要准备的
TemplateParam: `{"code":'${str}'}`, // 短信模板变量对应的实际值,JSON格式
})
.then((result) => {
let { Code } = result;
if (Code == "OK") {
let r = formatResponse(1, str);
res.send(r);
console.log(result);
}
})
.catch((err) => {
let r = formatResponse(0, "发送失败");
console.log(err);
res.send(r);
});
});
module.exports = router;