Files
competition-website/app/service/sms.js

79 lines
2.7 KiB
JavaScript
Raw Normal View History

'use strict';
const Service = require('egg').Service;
/**
* 短信网关服务(阿里云 Dysmsapi)
*
* 仅负责把"服务端已生成的验证码"下发给手机号,不参与验证码的存证与校验
* (校验仍由 ctx.session 在 auth 控制器中完成,契约见 verify_sms_and_import_lock 测试)。
*
* 依赖 SDK(生产环境需 npm install):
* @alicloud/openapi-client
* @alicloud/dysmsapi20170525
* @alicloud/tea-util
*/
class SmsService extends Service {
/**
* 发送短信验证码
* @param {string} phone - 接收短信的手机号
* @param {string} code - 6 位验证码(由调用方生成并存入 session)
* @returns {Promise<{ok:boolean, message:string}>}
*/
async sendVerifyCode(phone, code) {
const { ctx, app } = this;
const cfg = app.config.sms && app.config.sms.aliyun;
if (!cfg || !cfg.accessKeyId || !cfg.accessKeySecret) {
ctx.logger.error('[短信网关] 未配置阿里云密钥,无法发送');
return { ok: false, message: '短信网关未配置' };
}
let OpenApi;
let Dysmsapi;
let Util;
try {
OpenApi = require('@alicloud/openapi-client');
Dysmsapi = require('@alicloud/dysmsapi20170525');
Util = require('@alicloud/tea-util');
} catch (e) {
ctx.logger.error('[短信网关] 未安装阿里云 SDK:' + e.message);
return { ok: false, message: '短信网关 SDK 未安装' };
}
try {
const config = new OpenApi.Config({
accessKeyId: cfg.accessKeyId,
accessKeySecret: cfg.accessKeySecret,
endpoint: cfg.endpoint,
});
const client = new Dysmsapi.default(config);
const request = new Dysmsapi.SendSmsRequest({
phoneNumbers: String(phone),
signName: cfg.signName,
templateCode: cfg.templateCode,
templateParam: JSON.stringify({ code: String(code) }),
});
const runtime = new Util.RuntimeOptions({});
runtime.readTimeout = 5000;
runtime.connectTimeout = 5000;
const response = await client.sendSmsWithOptions(request, runtime);
const body = response && response.body;
if (body && body.code === 'OK') {
ctx.logger.info(`[短信网关] 验证码已下发至 ${phone}`);
return { ok: true, message: '验证码发送成功' };
}
const reason = (body && (body.message || body.code)) || '未知错误';
ctx.logger.error(`[短信网关] 下发失败:${reason}`);
return { ok: false, message: reason };
} catch (err) {
ctx.logger.error('[短信网关] 调用异常:' + (err && err.message));
return { ok: false, message: (err && err.message) || '短信网关调用异常' };
}
}
}
module.exports = SmsService;