Node.js实现阿里云短信服务发送短信(超级无敌详细)
·
1.进入阿里云
地址:云市场_镜像市场_软件市场_建站软件_服务器软件_AI应用_API接口_应用市场 - 阿里云
1.1 进入后点击控制台


1.2 在产品与服务中搜索短信服务

1.3 在国内消息中新增资质

1.4 在国内消息中新增签名(签名需要等运营商全部报备完成,否则短信可能会发送错误)
1.5 在国内消息中新增模板
1.6 在套餐包资费中购买国内通用短信套餐包
2.购买完成后,创建用户



2.1 创建好之后,要把账户的 accessKeyId 和 accessKeySecret 保存下来 ( 非常重要 !!! )

3.写代码
3.1 调用sdk
在node.js终端中安装:
$ npm install @alicloud/sms-sdk --save
$ npm install dotenv
$ npm install redis
3.2 dotenv 是一个在 Node.js 项目中常用的工具库,主要用于管理环境变量。
核心功能
1.环境变量管理:将项目配置(如数据库连接、API密钥等敏感信息)从代码中分离出来,存储在外部的 .env 文件中
2.安全保护:防止敏感信息(如密码、密钥)直接暴露在代码仓库中
3.多环境支持:方便地为不同环境(开发、测试、生产)配置不同的变量
工作原理
1.创建一个 .env 文件在项目根目录
2.在这个文件中以 KEY=VALUE 格式存储配置
3.在应用启动时,dotenv 会将这些变量加载到 process.env 中

3.2.1 代码
# 阿里云短信配置
ALIYUN_ACCESS_KEY_ID="您的AccessKey ID" # 您的AccessKey ID
ALIYUN_ACCESS_KEY_SECRET="您的Secret" # 您的Secret
# Redis 配置
REDIS_URL='您的Redis服务器地址' #您的Redis服务器地址
REDIS_PASSWORD='您的Redis访问密码' #您的Redis访问密码
3.3 在宝塔中配置 redis
3.3.1 在宝塔中安装redis

3.3.2 安装之后,点击redis 设置redis密码

3.3.3 进入配置文件 配置 bind 0.0.0.0(如果node.js后端代码已经上传到宝塔中,可以不动,如果没有上传到宝塔中,配置之后 Redis服务器地址写你的 公网ip)

3.3.4 protected-mode no # 关闭保护模式

3.3.5 配置好之后 点击重启服务

3.3.6 重启服务之后 在宝塔 安全 → 防火墙 放行 6379 端口。

3.4 完整代码
// 1. 环境变量加载(必须在所有模块导入前执行)
// 使用 dotenv 从 .env 文件加载环境变量到 process.env
require('dotenv').config();
const { createClient } = require('redis'); // Redis 客户端
// 2. 阿里云短信 SDK 导入
// 官方提供的 Node.js SDK,封装了短信发送接口
const SMSClient = require('@alicloud/sms-sdk');
// 初始化 Redis 客户端
const redisClient = createClient({
url: process.env.REDIS_URL, // Redis 连接地址
password: process.env.REDIS_PASSWORD // Redis 密码
});
// 监听 Redis 连接事件
redisClient.on('connect', () => {
console.log('Redis 客户端已连接');
});
redisClient.on('error', (err) => {
console.error('Redis 连接错误:', err);
});
// 3. 初始化短信客户端
// 注意:ALIYUN_ACCESS_KEY_ID 和 ALIYUN_ACCESS_KEY_SECRET 需在 .env 中配置
const smsClient = new SMSClient({
accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID, // 从环境变量读取访问密钥ID
secretAccessKey: process.env.ALIYUN_ACCESS_KEY_SECRET, // 从环境变量读取访问密钥
endpoint: 'https://dysmsapi.aliyuncs.com' // 阿里云短信服务API地址(不可更改)
});
// 连接 Redis
(async () => {
try {
await redisClient.connect();
console.log('Redis 连接成功');
} catch (err) {
console.error('Redis 连接失败:', err);
process.exit(1); // 如果 Redis 连接失败,退出应用
}
})();
/**
* 发送短信验证码
* @param {string} phoneNumber - 手机号码
* @param {number} [expireTime=300] - 验证码有效期(秒),默认5分钟
* @returns {Promise<Object>} 包含发送结果的对象
*/
// 4. 导出短信发送方法
exports.sendVerificationCode = async (req, res) => {
const {phoneNumber}=req.body
const expireTime=300 // 验证码有效期(秒),默认5分钟
try {
// 4.1 生成6位随机验证码(范围:100000-999999)
const verificationCode = Math.floor(100000 + Math.random() * 900000).toString();
// 4.2 生成唯一请求标识(防止重放攻击)
// 组合时间戳和随机字符串确保唯一性
const nonce = Date.now() + Math.random().toString(36).substring(2);
// 4.3 获取当前ISO格式时间戳(阿里云要求UTC时间)
const timestamp = new Date().toISOString();
// 4.4 存储验证码到Redis,设置过期时间
await redisClient.setEx(
`sms:verification:${phoneNumber}`, // Key格式: sms:verification:手机号
expireTime, // 过期时间(秒)
verificationCode // 验证码值
);
// 4.5 调用短信发送接口
const result = await smsClient.sendSMS({
PhoneNumbers: phoneNumber, // 接收号码
SignName: '短信签名', // 短信签名
TemplateCode: '短信模板CODE', // 短信模板CODE
TemplateParam: JSON.stringify({ code:verificationCode }), // 模板参数
__nonce: nonce, // 防重放随机数
__timestamp: timestamp // 当前时间戳
});
// 4.6 成功响应
res.send({
success: 0,
data: {
message: '短信发送成功', // 业务提示信息
requestId: result.RequestId, // 阿里云请求ID(用于排查问题)
}
});
} catch (error) {
// 4.7. 错误处理
console.error('[SMS_ERROR] 完整诊断:', {
message: error.message, // 错误描述
requestId: error.data?.RequestId, // 阿里云请求ID(重要!)
recommend: error.data?.Recommend, // 阿里云官方诊断链接
timestamp: new Date().toISOString() // 错误发生时间
});
// 4.8 失败响应
res.status(500).send({
success: 1,
message: '短信发送失败', // 用户友好提示
error:{ // 返回详细错误
error: error.message, // 原始错误信息
diagnoseUrl: error.data?.Recommend // 问题排查链接
}
});
}
};
/**
* 验证短信验证码
* @param {string} phoneNumber - 手机号码
* @param {string} inputCode - 用户输入的验证码
* @returns {Promise<Object>} 包含验证结果的对象
*/
// 验证短信验证码
exports.verifyCode = async (req, res) => {
const { phoneNumber, inputCode } = req.body;
try {
// 1. 从Redis获取存储的验证码
const storedCode = await redisClient.get(`sms:verification:${phoneNumber}`);
// 2. 检查验证码是否存在
if (!storedCode) {
return res.send({
status:1,
isValid: false,
message: '验证码已过期或不存在'
});
}
// 3. 比较验证码
if (storedCode !== inputCode) {
return res.send({
status:1,
isValid: false,
message: '验证码错误'
});
}
// 4. 验证成功,删除Redis中的验证码(防止重复使用)
await redisClient.del(`sms:verification:${phoneNumber}`);
return res.send({
status:0,
isValid: true,
message: '验证成功'
});
} catch (error) {
return res.status(500).send({
status:1,
isValid: false,
message: '验证服务异常',
});
}
}
3.4.1 完整代码(去掉redis版本)
// 1. 环境变量加载(必须在所有模块导入前执行)
// 使用 dotenv 从 .env 文件加载环境变量到 process.env
require('dotenv').config();
// 2. 阿里云短信 SDK 导入
// 官方提供的 Node.js SDK,封装了短信发送接口
const SMSClient = require('@alicloud/sms-sdk');
// 3. 初始化短信客户端
// 注意:ALIYUN_ACCESS_KEY_ID 和 ALIYUN_ACCESS_KEY_SECRET 需在 .env 中配置
const smsClient = new SMSClient({
accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID, // 从环境变量读取访问密钥ID
secretAccessKey: process.env.ALIYUN_ACCESS_KEY_SECRET, // 从环境变量读取访问密钥
endpoint: 'https://dysmsapi.aliyuncs.com' // 阿里云短信服务API地址(不可更改)
});
// 4. 导出短信发送方法
exports.SendVerificationCode = async (req, res) => {
try {
// 4.1 生成6位随机验证码(范围:100000-999999)
const verificationCode = Math.floor(100000 + Math.random() * 900000).toString();
// 4.2 生成唯一请求标识(防止重放攻击)
// 组合时间戳和随机字符串确保唯一性
const nonce = Date.now() + Math.random().toString(36).substring(2);
// 4.3 获取当前ISO格式时间戳(阿里云要求UTC时间)
const timestamp = new Date().toISOString();
const {phoneNumber}=req.body
// 4.4 调用短信发送接口
const result = await smsClient.sendSMS({
PhoneNumbers: phoneNumber, // 接收号码
SignName: '短信签名', // 短信签名
TemplateCode: '短信模板CODE', // 短信模板CODE
TemplateParam: JSON.stringify({ code:verificationCode }), // 模板变量(JSON格式)
__nonce: nonce, // 防重放随机数
__timestamp: timestamp // 当前时间戳
});
// 4.5 成功响应
res.send({
success: 0,
data: {
message: '短信发送成功', // 业务提示信息
requestId: result.RequestId, // 阿里云请求ID(用于排查问题)
}
});
} catch (error) {
// 5. 错误处理
console.error('[SMS_ERROR] 完整诊断:', {
message: error.message, // 错误描述
requestId: error.data?.RequestId, // 阿里云请求ID(重要!)
recommend: error.data?.Recommend, // 阿里云官方诊断链接
timestamp: new Date().toISOString() // 错误发生时间
});
// 5.1 失败响应
res.status(500).send({
success: 1,
message: '短信发送失败', // 用户友好提示
error:{ // 返回详细错误
error: error.message, // 原始错误信息
diagnoseUrl: error.data?.Recommend // 问题排查链接
}
});
}
};
3.5 使用 Apifox 调用发送短信接口

3.6 使用 Apifox 调用验证短信验证码接口

4.完结 🌼
更多推荐



所有评论(0)