手机短信使用的第三方平台是联容云,注册就送8块钱体验费,足够自己用用了,注册完自己建一个应用就能拿到需要使用的配置了,如图
注册完之后1就可以使用了。
Node.js后端使用了Express框架
"js-base64": "^3.7.2",
"blueimp-md5": "^2.19.0",
"moment": "^2.29.1",
"request": "^2.88.2"
这里引入了四个依赖
获取手机段短信方法
var md5 = require("blueimp-md5");
var moment = require("moment");
var Base64 = require("js-base64").Base64;
var request = require("request");
/*
生成指定长度的随机数
*/
function randomCode(length) {
var chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
var result = ""; //统一改名: alt + shift + R
for (var i = 0; i < length; i++) {
var index = Math.ceil(Math.random() * 9);
result += chars[index];
}
return result;
}
// console.log(randomCode(6));
exports.randomCode = randomCode;
/*
向指定号码发送指定验证码
*/
function sendCode(phone, code, callback) {
var ACCOUNT_SID = "";
var AUTH_TOKEN = "";
var Rest_URL = "";
var AppID = "";
//1. 准备请求url
/*
1.使用MD5加密(账户Id + 账户授权令牌 + 时间戳)。其中账户Id和账户授权令牌根据url的验证级别对应主账户。
时间戳是当前系统时间,格式"yyyyMMddHHmmss"。时间戳有效时间为24小时,如:20140416142030
2.SigParameter参数需要大写,如不能写成sig=abcdefg而应该写成sig=ABCDEFG
*/
var sigParameter = "";
var time = moment().format("YYYYMMDDHHmmss");
sigParameter = md5(ACCOUNT_SID + AUTH_TOKEN + time);
var url =
Rest_URL +
"/2013-12-26/Accounts/" +
ACCOUNT_SID +
"/SMS/TemplateSMS?sig=" +
sigParameter;
//2. 准备请求体
var body = {
to: phone,
appId: AppID,
templateId: "1",
datas: [code, "1"],
};
//body = JSON.stringify(body);
//3. 准备请求头
/*
1.使用Base64编码(账户Id + 冒号 + 时间戳)其中账户Id根据url的验证级别对应主账户
2.冒号为英文冒号
3.时间戳是当前系统时间,格式"yyyyMMddHHmmss",需与SigParameter中时间戳相同。
*/
var authorization = ACCOUNT_SID + ":" + time;
authorization = Base64.encode(authorization);
var headers = {
Accept: "application/json",
"Content-Type": "application/json;charset=utf-8",
"Content-Length": JSON.stringify(body).length + "",
Authorization: authorization,
};
//4. 发送请求, 并得到返回的结果, 调用callback
// callback(true);
request(
{
method: "POST",
url: url,
headers: headers,
body: body,
json: true,
},
function (error, response, body) {
callback(body.statusCode === "000000");
}
);
}
exports.sendCode = sendCode;
使用:引入上面的方法,将请求的mobile和生成的code验证码传入进行保存在sendCodeP数组中进行保存,并开启计时器在120s后进行删除。
const { randomCode, sendCode } = require("../utils/getMessage");
const { valid } = require("../utils/valid")
var sqlQuery = require("../utils/dbconfig");
const jwt = require("../utils/token");
let sendCodeP = []
//倒计时
setTime = function (mobile, code) {
sendCodeP.push({
mobile:mobile,
code:code
})
let i = 0
let timer = setInterval(() => {
i += 1
console.log(i)
if (i == 120) {
const index = sendCodeP.findIndex(e => {
return e.mobile == mobile
})
sendCodeP.splice(index, 1)
clearInterval(timer)
}
}, 1000);
}
sendMobileCode = (req, res) => {
const { mobile } = req.query
console.log(mobile)
if (!valid.mobileFormatting.test(mobile)) {
res.send({
msg: "手机号格式错误",
status: 402,
});
} else {
const index=sendCodeP.findIndex(e=>{
return e.mobile===mobile
})
if (index!=-1) {
res.send({
status: 402,
msg: "已经发送过",
});
}
else {
let code = randomCode(6);
sendCode(mobile, code, function (success) {
if (success) {
setTime(mobile, code)
res.send({
status: 0,
msg: '短信验证码已发送'
});
} else {
res.send({
status: 402,
msg: "短信验证码发送失败"
});
}
});
}
}
}
login = async function (mobile) {
var sql = `select * from cms_user where mobile='${mobile}'`;
let arr = []
let data = await sqlQuery(sql, arr)
return data
}
//验证码登陆
codePhoneLogin = async (req, res) => {
let { mobile, Verification } = req.query;
console.log(sendCodeP, mobile)
//验证手机号是否发送过验证码
const index=sendCodeP.findIndex(e=>{
return e.mobile===mobile
})
console.log(index)
if (index!=-1) {
//验证验证码与手机号是否匹配
if (Verification==sendCodeP[index].code) {
const loginData = await login(mobile)
if (loginData && loginData.length != 0) {
delete loginData[0]["password"];
const tokenstr = jwt.encrypt({ gadID: loginData[0].id }, "2h");
res.send({
data: loginData[0],
token: tokenstr,
msg: `登录成功`,
status: 0,
});
} else {
res.send({
msg: `无账号信息`,
status: 402,
});
}
} else {
res.send({
status: 402,
msg: "验证码错误",
});
}
} else {
res.send({
status: 402,
msg: "请先获取验证码",
});
}
};
module.exports = {
sendMobileCode,
codePhoneLogin
}
Vue调用接口即可实现手机短信验证
附上前端短信登录代码
<template>
<div>
<el-form
:model="ruleForm"
status-icon
:rules="rules_register"
ref="ruleForm"
label-width="60px"
class="demo-ruleForm"
>
<el-form-item label="手机号" prop="mobile">
<el-input type="text" v-model="ruleForm.mobile" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="验证码" prop="Verification">
<el-input style="width: 150px" v-model="ruleForm.Verification"></el-input>
<el-button
type="primary"
style="margin-left: 20px"
@click="getCode"
:disabled="Boolean(timer)"
>{{btnName}}</el-button>
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button>重置</el-button>
<el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
</div>
</div>
</template>
<script>
export default {
data() {
var validateMobile = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入手机号"));
} else {
if (!this.$valid.mobileFormatting.test(value)) {
callback(new Error("请输入正确的手机号"));
}
callback();
}
};
var validateVerification = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入验证码"));
} else {
if (!this.$valid.VerificationFormatting.test(value)) {
callback(new Error("请输入6位验证码"));
}
callback();
}
};
return {
ruleForm: {},
timer: null,
i: 0,
btnName: "获取验证码",
rules_register: {
mobile: [{ validator: validateMobile, trigger: "blur" }],
Verification: [{ validator: validateVerification, trigger: "blur" }]
}
};
},
methods: {
getCode() {
if (!this.ruleForm.mobile || this.ruleForm.mobile == "") {
this.$message.error("请先输入手机号");
return;
} else if (!this.$valid.mobileFormatting.test(this.ruleForm.mobile)) {
this.$message.error("手机号格式错误");
return;
} else {
this.$getRequest("/sendCode", { mobile: this.ruleForm.mobile }).then(
res => {
if (res.status === 0) {
this.$message.success(res.msg);
this.timer = setInterval(() => {
this.i += 1;
this.btnName = `已发送(${60 - this.i})`;
if (this.i === 60) {
this.btnName = "重新获取";
clearInterval(this.timer);
}
}, 1000);
}
}
);
}
},
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.$getRequest("/codePhoneLogin", this.ruleForm).then(res => {
if (res.status == 0) {
// this.$message.success(`登录成功,欢迎你 ${res.data[0].name}`);
let time = new Date().getHours();
console.log(time);
let title;
if (time < 12) {
title = "早上好";
} else if (12 <= time && time < 18) {
console.log(time);
title = "下午好";
} else {
title = "晚上好";
}
this.$notify({
title: "登录成功",
message: title + " " + res.data.name,
type: "success"
});
this.$router.replace("/main");
}
});
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
};
</script>
<style>
</style>
手机短信验证登录就是这么简单,看过就能自己实现一个了。