Node.js接入阿里云短信验证码服务

617 阅读1分钟

阿里云的文档真的是一比糟,折腾了半天。提供给使用Node的小伙伴参考。
数据库:MongoDB,使用 CommonJS 模块语法。

首先,创建smsCode的Schema:./models/smsCode.js
设置过期时间10分钟(10分钟后会自动删除)

const mongoose = require("mongoose");

const smsCodeSchema = new mongoose.Schema({
    phoneNumber: String,
    code: String,
    createdAt: { type: Date, expires: 60 * 10, default: Date.now }, // 设定验证码过期时间,10分钟
});

module.exports = mongoose.model("SmsCode", smsCodeSchema);

创建SMSClient.js

const $OpenApi = require("@alicloud/openapi-client");
const $Util = require("@alicloud/tea-util");

class SMSClient {
  constructor(accessKeyId, accessKeySecret) {
    this.config = new $OpenApi.Config({
      accessKeyId: accessKeyId,
      accessKeySecret: accessKeySecret,
    });
    this.config.endpoint = "dysmsapi.aliyuncs.com";
    this.client = new $OpenApi.default(this.config);
  }

  static createApiInfo() {
    const params = new $OpenApi.Params({
      action: "SendSms",
      version: "2017-05-25",
      protocol: "HTTPS",
      method: "POST",
      authType: "AK",
      style: "RPC",
      pathname: "/",
      reqBodyType: "json",
      bodyType: "json",
    });
    return params;
  }

  async sendSms(mobile, signName, templateCode, templateParam) {
    const params = SMSClient.createApiInfo();
    const runtime = new $Util.RuntimeOptions({});
    const request = new $OpenApi.OpenApiRequest({
      query: {
        PhoneNumbers: mobile,
        SignName: signName,
        TemplateCode: templateCode,
        TemplateParam: JSON.stringify(templateParam),
      },
    });

    try {
      const response = await this.client.callApi(params, request, runtime);
      return response;
    } catch (error) {
      console.error(`发送验证码失败: ${error.message}`);
      throw error;
    }
  }
}

module.exports = SMSClient;

发送验证码和校验验证码的路由,记得一定要替换成你的参数和配置项

const SMSCode = require("../models/smsCode");
const SMSClient = require("./smsClient");

//...

//发送验证码
router.post("/send_sms_code", async (req, res) => {
    const { mobile } = req.body;    //根据情况修改成你的参数命名
    // 生成验证码
    const code = (Math.floor(Math.random() * 9000) + 1000).toString();
    // 创建阿里云短信服务客户端
    const client = new SMSClient(
        "LTAI5t9HV2oNxpXNg4HQJjP",//替换成你的accessKeyId
        "0nFvjMNFZOosk5GlUMeAzosGjDCKi"//替换成你的accessKeySecret
    );
    try {
        // 发送短信验证码
        //这里替换成你的SignName短信签名名称,TemplateCode短信模板CODE,TemplateParam短信模板变量
        await client.sendSms(mobile, "数字简历", "SMS_27628717", {
            code: code,
        });
        // 保存验证码到数据库
        const smsCode = new SMSCode({
            phoneNumber: mobile,
            code: code,
        });

        await smsCode.save();

        console.log(`验证码已发送到手机号 ${mobile}`);
        res.status(200).json({ message: "发送成功" });
    } catch (error) {
        console.error(`发送验证码失败: ${error.message}`);
        res.status(500).json({ message: error.message });
    }
});

//校验验证码
//这里根据你的情况,修改手机号的参数
router.post("/verify_sms_code", async (req, res) => {
    try {
        const { mobile, code } = req.body;

        if (!mobile || !code) {
            return res.status(400).json({ message: "手机号和验证码不能为空" });
        }

        const existingCode = await SMSCode.findOne({ phoneNumber: mobile });

        if (!existingCode) {
            return res.status(404).json({ message: "无效的验证码或验证码已过期" });
        }

        if (existingCode.code !== code) {
            return res.status(400).json({ message: "验证码不正确" });
        }

        res.status(200).json({ message: "验证成功" });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});