目录
🧩 一、短信接口的整体工作流程
1. 向短信平台注册账号
2. 获取必要信息
3. 后端发起 HTTPS 请求
4. 平台验证并发送
🔐 二、安全机制设计(重点)
🛠️ 三、示例:调用短信 API(以腾讯云为例)
📦 四、常见短信平台推荐
✅ 功能说明
🛠️ 项目依赖(Python)
📦 项目结构(简化
🔑 config.py
💬 tencent_sms.py(封装腾讯云短信发送)
🚀 app.py(主程序)
📲 示例请求(用 Postman 或前端)
🧪 测试建议
短信接口(SMS API)的原理并不复杂,但它涉及到多个环节,包括:
-
第三方短信平台(如阿里云、腾讯云、Twilio)
-
HTTP 请求通信机制
-
验证签名、限流、模板审核等安全措施
🧩 一、短信接口的整体工作流程
假设你要开发一个“发送验证码”的功能,大致流程如下:
1. 向短信平台注册账号
你首先要在像阿里云短信服务、腾讯云短信、Twilio 等平台注册,申请接口权限。
2. 获取必要信息
你需要以下信息来调用 API:
-
API 访问地址(Endpoint)
-
Access Key(用于认证身份)
-
短信签名(Sender ID,如【你的应用名】)
-
短信模板(事先设定好的内容格式,比如“验证码为:${code},请在5分钟内输入。”)
3. 后端发起 HTTPS 请求
你的后端服务器调用平台提供的 API,一般是一个 POST 请求,内容包含:
{"phone_number": "13812345678","template_id": "123456","template_param": {"code": "648291"},"sign_name": "【应用名】","access_key": "你自己的Key"
}
4. 平台验证并发送
平台接收请求后,会验证请求合法性,包括:
-
签名是否正确
-
模板内容是否一致
-
请求是否超出频率限制
验证通过后,平台将短信发送到运营商(移动、联通、电信),再由运营商投递到用户手机。
🔐 二、安全机制设计(重点)
短信接口容易被滥用,所以平台通常加入以下防护机制:
机制 | 说明 |
---|---|
访问频率限制 | 每个 IP、每个手机号、每个账号 每分钟/每小时/每天最多发送几条短信。 |
模板审核 | 所有短信必须使用模板,平台审核通过后才可使用,防止发送恶意内容。 |
签名机制 | 请求中要加入签名参数(如 HMAC、SHA256),防止伪造请求。 |
验证码发送频控 | 典型规则是“每个手机号每60秒最多发送一次验证码”,避免短信轰炸。 |
图形验证码预验证 | 有时前端要先通过图形验证码验证,才能请求发送短信。 |
🛠️ 三、示例:调用短信 API(以腾讯云为例)
import requests
import json
from tencentcloud.sms.v20210111 import sms_client, models# 用伪代码举例
url = "https://sms.tencentcloudapi.com"
headers = {"Authorization": "你的签名","Content-Type": "application/json"
}
data = {"PhoneNumberSet": ["+8613812345678"],"SmsSdkAppId": "1400006666","SignName": "你的短信签名","TemplateId": "123456","TemplateParamSet": ["648291"]
}response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json())
📦 四、常见短信平台推荐
名称 | 优点 | 网址 |
---|---|---|
腾讯云短信 | 中文文档好,国内投递成功率高 | https://cloud.tencent.com/product/sms |
阿里云短信 | 支持国际发送,服务成熟 | https://dysms.console.aliyun.com/ |
Twilio | 海外开发者首选,文档完善 | https://www.twilio.com/sms |
下面是一个完整的短信验证码发送系统后端示例,使用:
-
Flask:作为后端框架
-
Redis:存储验证码及冷却时间
-
腾讯云短信 API:用于发送短信验证码
✅ 功能说明
实现以下功能:
-
用户发送手机号,请求获取验证码;
-
验证冷却时间(60秒内不能重复发);
-
随机生成验证码(6位);
-
存入 Redis,有效期 5 分钟;
-
调用腾讯云短信 API 发送短信。
🛠️ 项目依赖(Python)
先安装依赖:
pip install flask redis tencentcloud-sdk-python sms
📦 项目结构(简化
sms_project/
├── app.py # Flask 主程序
├── tencent_sms.py # 腾讯云短信工具
└── config.py # 配置文件
🔑 config.py
# config.pyTENCENT_SMS_APP_ID = "1400XXXXXXX"
TENCENT_SMS_SECRET_ID = "你的SecretId"
TENCENT_SMS_SECRET_KEY = "你的SecretKey"
TENCENT_SMS_SIGN_NAME = "你的短信签名"
TENCENT_SMS_TEMPLATE_ID = "123456" # 验证码模板IDREDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DB = 0
💬 tencent_sms.py(封装腾讯云短信发送)
# tencent_sms.pyfrom tencentcloud.sms.v20210111 import sms_client, models
from tencentcloud.common import credential
from config import *def send_sms(phone, code):cred = credential.Credential(TENCENT_SMS_SECRET_ID, TENCENT_SMS_SECRET_KEY)client = sms_client.SmsClient(cred, "ap-guangzhou")req = models.SendSmsRequest()req.SmsSdkAppId = TENCENT_SMS_APP_IDreq.SignName = TENCENT_SMS_SIGN_NAMEreq.TemplateId = TENCENT_SMS_TEMPLATE_IDreq.TemplateParamSet = [code]req.PhoneNumberSet = [f"+86{phone}"]client.SendSms(req)
🚀 app.py(主程序)
# app.pyfrom flask import Flask, request, jsonify
import random
import redis
from tencent_sms import send_sms
from config import *app = Flask(__name__)r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)@app.route('/send-code', methods=['POST'])
def send_code():data = request.jsonphone = data.get("phone")if not phone:return jsonify({"code": 400, "msg": "缺少手机号"}), 400cooldown_key = f"sms_cooldown:{phone}"code_key = f"sms_code:{phone}"# 冷却时间检查(60秒)if r.get(cooldown_key):return jsonify({"code": 429, "msg": "请求太频繁,请稍后再试"}), 429# 生成验证码code = str(random.randint(100000, 999999))# 存入 Redisr.setex(code_key, 300, code) # 验证码有效期5分钟r.setex(cooldown_key, 60, "1") # 冷却期60秒try:send_sms(phone, code)return jsonify({"code": 200, "msg": "验证码发送成功"})except Exception as e:return jsonify({"code": 500, "msg": f"短信发送失败:{str(e)}"}), 500if __name__ == '__main__':app.run(debug=True)
📲 示例请求(用 Postman 或前端)
POST http://localhost:5000/send-code
Content-Type: application/json{"phone": "13812345678"
}
🧪 测试建议
-
腾讯云短信控制台里可以申请测试模板和测试号码,避免真实扣费;
-
Redis 可以用 Docker 快速启动
docker run -p 6379:6379 redis