阿里云短信服务实现用户注册(个人)"/>
【Node】Koa调用阿里云短信服务实现用户注册(个人)
目录
一. 购买
1. 在阿里云首页搜索框搜索“短信验证码”
2. 选择其中一个并购买
二. 代码实现
0. 研究示例代码
1. 发送短信验证码
2. 在数据库中保存短信验证码等信息
3. 校验输入的注册信息
4. 注册
一. 购买
没有企业资质,个人想要调用阿里云短信服务,我的解决办法是购买其他公司已经开通的阿里云短信服务。
1. 在阿里云首页搜索框搜索“短信验证码”
2. 选择其中一个并购买
我选择的是这个,有提供免费次数,价格相对比较实惠
链接:【体验价2分5】三网短信接口-短信验证码-通知短信-短信验证码接口-三网短信接口-短信通知-短信验证码-验证码短信-服务短信【最新版】_商业智能_电商_金融-云市场-阿里云
购买成功后可以在 已购买的服务【阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台】 中看到短信验证码的AppKey、AppSecret、AppCode这些信息
二. 代码实现
0. 研究示例代码
购买页下面有请求示例,但是并没有Nodejs的示例,这就让我头疼了很久(框起来的信息都非常重要,要看仔细了);
后来我在这个链接中【阿里云 OpenAPI 开发者门户】找到了Node.js版本的调用示例。
1. 发送短信验证码
async sendMessage(ctx, next) {const customerPhoneNumber = ctx.request.query.customerPhoneNumber;const AppCode = "<your-AppCode>"const AppKey = "<your-AppKey>"const AppSecret = "<your-AppSecret>"const Host = "" // 购买页示例中的主机地址const Path = "/data/send_sms" // 购买页示例中的路径const templateId = "TPL_0000" // 购买页示例中的模板编号const client = new Core({accessKeyId: AppKey,accessKeySecret: AppSecret,endpoint: Host + Path,apiVersion: '2017-05-25'});// 生成n位随机0~9的验证码const geneRandomCode = (n) => {let code = ""for (let i = 0; i < n; i++) {code += parseInt(Math.random() * 10)}return code}const code = geneRandomCode(6)const params = {content: `code:${code}`,["phone_number"]: customerPhoneNumber,["template_id"]: templateId}const requestOption = {method: 'POST',formatParams: false,headers: {Authorization: `APPCODE ${AppCode}`,["Content-Type"]: "application/x-www-form-urlencoded; charset=UTF-8"}}try {const response = await client.request('SendSms', params, requestOption)// console.log('response', response)if (response.status === 'OK') {const message = {customerPhoneNumber,code,expirationTime: new Date().getTime() + EXPIRATION_TIME + ""}console.log(message);// 在数据库中保存用户手机号+短信验证码+过期时间戳await userService.saveSMSCode(message)ctx.body = {code: '200',message: '发送成功'}} else {ctx.body = {code: '400',message: '发送失败'}}} catch (error) {console.log('error', error)}
}
expirationTime过期时间我是通过getTime的方法获取当前的13位时间戳(单位毫秒ms),再加上一个常量
const EXPIRATION_TIME = 1000 * 60 * 5 // 5分钟
2. 在数据库中保存短信验证码等信息
讲道理在Redis中保存短信验证码设置过期时间会更加规范,简单起见我就保存在MySQL里了。
async saveSMSCode(message) {const {customerPhoneNumber,code,expirationTime} = messagelet statement = `SELECT * FROM smscode WHERE customerPhoneNumber = ?`let result = await connection.execute(statement, [customerPhoneNumber])// 如果查不到就插入新的数据 查到了就更新替换短信验证码 + 过期时间if (result[0].length === 0) {statement = `INSERT INTO smscode (customerPhoneNumber, code, ExpirationTime) VALUES(?, ?, ?)`result = await connection.execute(statement, [customerPhoneNumber, code, expirationTime])} else {statement = `UPDATE smscode SET code = ? , ExpirationTime = ? WHERE customerPhoneNumber = ?`result = await connection.execute(statement, [code, expirationTime, customerPhoneNumber])}
}
3. 校验输入的注册信息
编写中间件verifyRegisterInfo对用户输入的注册信息进行校验;
主要从三个方面进行校验:
- 判断用户输入的信息是否合法,例如手机号长度等
- 在数据库中查询用户输入的手机号是否被注册过
- 查看验证码是否正确并未过期
const verifyRegisterInfo = async (ctx, next) => {const {customerPhoneNumber,code} = ctx.request.bodytry {// 1. 判断用户填入信息是否合法// 前端已经判断// 2. 查询手机号是否被注册过let result = await userService.getPhone(customerPhoneNumber)// console.log("查询手机号是否被注册过:", result);if (result.length !== 0) {const error = new Error(errorType.PHONE_ALREADY_EXISTS)return ctx.app.emit("error", error, ctx)}// 3. 查看验证码是否正确或过期const message = {customerPhoneNumber,code,curTime: new Date().getTime()}result = await userService.checkCode(message)// console.log("查看验证码是否正确或过期:", result);if (result.length === 0) {const error = new Error(errorType.CODE_IS_EXPIRED_OR_INCORRECT)return ctx.app.emit("error", error, ctx)}await next()} catch (err) {console.log(err);}
}
若用户传入的注册信息不合法,则会抛出错误,若没有错误则会执行next(),交给下一个中间件register处理
async getPhone(customerPhoneNumber) {let statement = `SELECT * FROM customer WHERE customer_phone_number = ?`let result = await connection.execute(statement, [customerPhoneNumber])return result[0]
}async checkCode(message) {const {customerPhoneNumber,code,curTime} = messageconst statement = `SELECT * FROM smscode WHERE customerPhoneNumber = ? AND code = ? AND expirationTime >= ?`const result = await connection.execute(statement, [customerPhoneNumber, code, curTime])return result[0]
}
4. 注册
编写中间件register;
在数据库中插入用户注册的数据;
async register(ctx, next) {const {customerPhoneNumber,customerPassword} = ctx.request.bodyconst message = {customerPhoneNumber,customerPassword}await userService.register(message)ctx.body = {status: 200,message: "注册成功~"}
}
async register(message) {const {customerPhoneNumber,customerPassword} = messagelet statement = `INSERT INTO customer (customer_phone_number, customer_password) VALUES(?, ?)`const result = await connection.execute(statement, [customerPhoneNumber, customerPassword])return result[0]
}
以上步骤便完整了通过Koa调用阿里云短信服务实现用户注册的功能。
更多推荐
【Node】Koa调用阿里云短信服务实现用户注册(个人)
发布评论