功能:阿里云号码认证短信 provider + sms.py 拆为可切换 provider 包
现有 sms.py(极光自管码)升级为 app/integrations/sms/ 包:
- base : SmsError + provider 无关的 mock_verify
- jiguang: 原极光自管码逻辑逐字迁入,行为零改动(git 识别为 sms.py 的 rename)
- aliyun : 新增阿里云 dypns 号码认证(Mode A:阿里云生成+下发+校验,核验免费)
- __init__: 按 SMS_PROVIDER 每次调用路由的分派器(默认 jiguang,可秒切回退)
关键决策:
- Mode A:发码 SendSmsVerifyCode(##code## 占位)、校验 CheckSmsVerifyCode(PASS/UNKNOWN);
本服务不再存码 → 消除极光路径「内存存码、多 worker 不共享」技术债。
- 防爆破与极光一致:aliyun 保留 per-phone 失败计数(SMS_MAX_VERIFY_ATTEMPTS),达上限本地作废,
避免两 provider 行为不同致排查困惑(此为 aliyun 路径唯一本地态)。
- 校验降级:阿里云接口异常 → verify_code 抛 SmsError(503),auth 两处 try/except 透出 503(非误报 400)。
- 官方 SDK alibabacloud_dypnsapi20170525;SDK 交互隔离在 _call_send/_call_check(惰性 import + 惰性建
client),单测 monkeypatch 不触真网络。
测试:test_sms_aliyun(17)+ test_sms_dispatch(3)全绿;test_auth 内部访问 retarget 到 jiguang.*。
配置:SMS_PROVIDER + ALIYUN_SMS_*(见 .env.example);文档 docs/integrations/sms.md + aliyun 接口参考。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
CheckSmsVerifyCode - 核验验证码
|
||||
更新时间:2026年3月19日 20:02:53
|
||||
核验短信验证码并返回核验是否成功的结果。
|
||||
|
||||
调试
|
||||
您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。
|
||||
|
||||
调试
|
||||
授权信息
|
||||
下表是API对应的授权信息,可以在RAM权限策略语句的Action元素中使用,用来给RAM用户或RAM角色授予调用此API的权限。具体说明如下:
|
||||
|
||||
操作:是指具体的权限点。
|
||||
|
||||
访问级别:是指每个操作的访问级别,取值为写入(Write)、读取(Read)或列出(List)。
|
||||
|
||||
资源类型:是指操作中支持授权的资源类型。具体说明如下:
|
||||
|
||||
对于必选的资源类型,用前面加 * 表示。
|
||||
|
||||
对于不支持资源级授权的操作,用全部资源表示。
|
||||
|
||||
条件关键字:是指云产品自身定义的条件关键字。
|
||||
|
||||
关联操作:是指成功执行操作所需要的其他权限。操作者必须同时具备关联操作的权限,操作才能成功。
|
||||
|
||||
放大查看
|
||||
操作
|
||||
|
||||
访问级别
|
||||
|
||||
资源类型
|
||||
|
||||
条件关键字
|
||||
|
||||
关联操作
|
||||
|
||||
dypns:CheckSmsVerifyCode
|
||||
|
||||
none
|
||||
|
||||
*全部资源
|
||||
|
||||
*
|
||||
|
||||
无 无
|
||||
请求参数
|
||||
放大查看
|
||||
名称
|
||||
|
||||
类型
|
||||
|
||||
必填
|
||||
|
||||
描述
|
||||
|
||||
示例值
|
||||
|
||||
SchemeName
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
方案名称,如果不填则为“默认方案”。最多不超过 20 个字符。
|
||||
|
||||
重要 如果发送接口的方案名称不为空,请确保该参数不为空且与发送接口的方案名称参数一致
|
||||
测试方案
|
||||
|
||||
CountryCode
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
号码国家编码,默认为 86。
|
||||
|
||||
86
|
||||
|
||||
PhoneNumber
|
||||
string
|
||||
|
||||
是
|
||||
|
||||
手机号。
|
||||
|
||||
186****0000
|
||||
|
||||
OutId
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
外部流水号。
|
||||
|
||||
12123231
|
||||
|
||||
VerifyCode
|
||||
string
|
||||
|
||||
是
|
||||
|
||||
验证码。
|
||||
|
||||
说明
|
||||
SendSmsVerifyCode 接口的字段 TemplateParam,配置方式有 2 种:
|
||||
|
||||
{"code":"##code##","min":"5"}
|
||||
|
||||
{"code":"123456","min":"5"}
|
||||
|
||||
{"code":"##code##","min":"5"}验证码是 api 动态生成的,阿里云接口可以完成校验。
|
||||
|
||||
{"code":"123456","min":"5"}验证码是用户配置的不是 api 动态生成,阿里云接口无法校验。
|
||||
|
||||
请您按照实际情况传入对应的验证码。
|
||||
|
||||
1231
|
||||
|
||||
CaseAuthPolicy
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
验证码大小写字母核验策略。取值:
|
||||
|
||||
1:不区分大小写。
|
||||
|
||||
2:区分大小写。
|
||||
|
||||
1
|
||||
|
||||
返回参数
|
||||
放大查看
|
||||
名称
|
||||
|
||||
类型
|
||||
|
||||
描述
|
||||
|
||||
示例值
|
||||
|
||||
object
|
||||
|
||||
AccessDeniedDetail
|
||||
string
|
||||
|
||||
访问被拒绝详细信息。
|
||||
|
||||
无
|
||||
|
||||
Message
|
||||
string
|
||||
|
||||
状态码的描述。
|
||||
|
||||
成功
|
||||
|
||||
Model
|
||||
object
|
||||
|
||||
请求结果数据。
|
||||
|
||||
OutId
|
||||
string
|
||||
|
||||
外部流水号。
|
||||
|
||||
1212312
|
||||
|
||||
VerifyResult
|
||||
string
|
||||
|
||||
短信验证码核验结果。取值:
|
||||
|
||||
PASS:短信验证码核验成功。
|
||||
|
||||
UNKNOWN:短信验证码核验失败。
|
||||
|
||||
PASS
|
||||
|
||||
Code
|
||||
string
|
||||
|
||||
接口请求状态码。
|
||||
|
||||
返回 OK 代表请求成功。
|
||||
|
||||
其他错误码,请参见返回码。
|
||||
|
||||
重要 接口请求成功不代表短信验证码核验成功,短信验证码核验结果仅以Model.VerifyResult参数返回值为准。
|
||||
OK
|
||||
|
||||
Success
|
||||
boolean
|
||||
|
||||
接口调用是否成功。取值:
|
||||
|
||||
true:接口调用成功。
|
||||
|
||||
false:接口调用失败。
|
||||
|
||||
重要 接口调用成功不代表短信验证码核验成功,短信验证码核验结果仅以Model.VerifyResult参数返回值为准。
|
||||
true
|
||||
|
||||
RequestId
|
||||
string
|
||||
|
||||
CF8854E5-DB21-3E5D-A9B1-DDC752FD7384
|
||||
|
||||
示例
|
||||
正常返回示例
|
||||
|
||||
JSON格式
|
||||
|
||||
放大查看复制代码
|
||||
{
|
||||
"AccessDeniedDetail": "无",
|
||||
"Message": "成功",
|
||||
"Model": {
|
||||
"OutId": "1212312",
|
||||
"VerifyResult": "PASS"
|
||||
},
|
||||
"Code": "OK",
|
||||
"Success": true,
|
||||
"RequestId": "CF8854E5-DB21-3E5D-A9B1-DDC752FD7384"
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
SendSmsVerifyCode - 发送短信验证码
|
||||
更新时间:2026年7月3日 09:54:53
|
||||
发送短信验证码。
|
||||
|
||||
接口说明
|
||||
由于运营商近期加强对短信签名的管控。您自定义的签名面临下发失败问题,推荐您使用号码认证控制台赠送的短信签名和模板进行短信认证。系统赠送签名必须搭配系统赠送模板使用。
|
||||
|
||||
请确保在使用该接口前,已充分了解号码认证服务产品的收费方式和价格,短信认证服务仅收取短信发送费用(按运营商回执状态计费,短信提交成功但运营商回执失败时不计费),核验服务免费。
|
||||
|
||||
调试
|
||||
您可以在OpenAPI Explorer中直接运行该接口,免去您计算签名的困扰。运行成功后,OpenAPI Explorer可以自动生成SDK代码示例。
|
||||
|
||||
调试
|
||||
授权信息
|
||||
下表是API对应的授权信息,可以在RAM权限策略语句的Action元素中使用,用来给RAM用户或RAM角色授予调用此API的权限。具体说明如下:
|
||||
|
||||
操作:是指具体的权限点。
|
||||
|
||||
访问级别:是指每个操作的访问级别,取值为写入(Write)、读取(Read)或列出(List)。
|
||||
|
||||
资源类型:是指操作中支持授权的资源类型。具体说明如下:
|
||||
|
||||
对于必选的资源类型,用前面加 * 表示。
|
||||
|
||||
对于不支持资源级授权的操作,用全部资源表示。
|
||||
|
||||
条件关键字:是指云产品自身定义的条件关键字。
|
||||
|
||||
关联操作:是指成功执行操作所需要的其他权限。操作者必须同时具备关联操作的权限,操作才能成功。
|
||||
|
||||
放大查看
|
||||
操作
|
||||
|
||||
访问级别
|
||||
|
||||
资源类型
|
||||
|
||||
条件关键字
|
||||
|
||||
关联操作
|
||||
|
||||
dypns:SendSmsVerifyCode
|
||||
|
||||
create
|
||||
|
||||
*全部资源
|
||||
|
||||
*
|
||||
|
||||
无 无
|
||||
请求参数
|
||||
放大查看
|
||||
名称
|
||||
|
||||
类型
|
||||
|
||||
必填
|
||||
|
||||
描述
|
||||
|
||||
示例值
|
||||
|
||||
SchemeName
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
方案名称,如果不填则为“默认方案”。最多不超过 20 个字符。
|
||||
|
||||
测试方案
|
||||
|
||||
CountryCode
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
号码国家编码。默认为 86,目前也仅支持国内号码发送。
|
||||
|
||||
86
|
||||
|
||||
PhoneNumber
|
||||
string
|
||||
|
||||
是
|
||||
|
||||
短信接收方手机号。
|
||||
|
||||
130****0000
|
||||
|
||||
SignName
|
||||
string
|
||||
|
||||
是
|
||||
|
||||
签名名称。暂不支持使用自定义签名,请使用系统赠送的签名,您可在赠送签名配置页面选择需要下发的签名。
|
||||
|
||||
恒创联众
|
||||
|
||||
TemplateCode
|
||||
string
|
||||
|
||||
是
|
||||
|
||||
短信模板 CODE。参数SignName选择赠送签名时,必须搭配赠送模板下发短信。您可在赠送模板配置页面选择适用您业务场景的模板。
|
||||
|
||||
100001
|
||||
|
||||
TemplateParam
|
||||
string
|
||||
|
||||
是
|
||||
|
||||
短信模板参数。验证码位置有两种传值方式:
|
||||
|
||||
可使用"##code##"替代,由参数 CodeType 指定验证码生成规则;
|
||||
|
||||
也可直接传入具体的验证码值,直接下发至接收方。
|
||||
|
||||
示例:如模板内容为:“您的验证码是${code},有效期${min}分钟,请勿告诉他人。”。
|
||||
|
||||
重要 上文中的 code 请替换成您实际申请的验证码模板中的参数名称
|
||||
该字段可传入{"code":"##code##","min":"5"}由系统根据规则生成验证码;
|
||||
|
||||
或直接传入指定的验证码值{"code":"123456","min":"5"}。
|
||||
|
||||
说明
|
||||
{"code":"##code##","min":"5"}验证码是 api 动态生成的,阿里云接口可以完成校验。
|
||||
|
||||
{"code":"123456","min":"5"}验证码是用户配置的不是 api 动态生成,阿里云接口无法校验。
|
||||
|
||||
说明
|
||||
如果 JSON 中需要带换行符,请参照标准的 JSON 协议处理。
|
||||
|
||||
模板变量规范,请参见短信模板规范。
|
||||
|
||||
{"code":"##code##","min":"5"}
|
||||
|
||||
SmsUpExtendCode
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
上行短信扩展码。上行短信指发送给通信服务提供商的短信,用于定制某种服务、完成查询,或是办理某种业务等,需要收费,按运营商普通短信资费进行扣费。
|
||||
|
||||
说明
|
||||
扩展码是生成签名时系统自动默认生成的,不支持自行传入。无特殊需要此字段的用户请忽略此字段。如需使用,请联系您的商务经理。
|
||||
|
||||
1213123
|
||||
|
||||
OutId
|
||||
string
|
||||
|
||||
否
|
||||
|
||||
外部流水号。
|
||||
|
||||
外部流水号(透传)
|
||||
|
||||
CodeLength
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
验证码长度支持 4~8 位长度,默认是 4 位。
|
||||
|
||||
4
|
||||
|
||||
ValidTime
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
验证码有效时长,单位秒,默认为 300 秒。
|
||||
|
||||
300
|
||||
|
||||
DuplicatePolicy
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
核验规则,当有效时间内对同场景内的同号码重复发送验证码时,旧验证码如何处理。
|
||||
|
||||
1:覆盖处理(默认),即旧验证码会失效掉。
|
||||
|
||||
2:保留,即多个验证码都是在有效期内都可以校验通过。
|
||||
|
||||
枚举值:
|
||||
|
||||
1 :
|
||||
覆盖
|
||||
|
||||
2 :
|
||||
保留
|
||||
|
||||
1
|
||||
|
||||
Interval
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
时间间隔,单位:秒。即多久间隔可以发送一次验证码,用于频控,默认 60 秒。
|
||||
|
||||
60
|
||||
|
||||
CodeType
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
生成的验证码类型。当参数 TemplateParam 传入占位符时,此参数必填,将由系统根据指定的规则生成验证码。取值:
|
||||
|
||||
1:纯数字(默认)。
|
||||
|
||||
2:纯大写字母。
|
||||
|
||||
3:纯小写字母。
|
||||
|
||||
4:大小字母混合。
|
||||
|
||||
5:数字+大写字母混合。
|
||||
|
||||
6:数字+小写字母混合。
|
||||
|
||||
7:数字+大小写字母混合。
|
||||
|
||||
枚举值:
|
||||
|
||||
1 :
|
||||
纯数字
|
||||
|
||||
2 :
|
||||
纯大写字母
|
||||
|
||||
3 :
|
||||
纯小写字母
|
||||
|
||||
4 :
|
||||
大小字母混合
|
||||
|
||||
5 :
|
||||
数字+大写字母混合
|
||||
|
||||
6 :
|
||||
数字+小写字母混合
|
||||
|
||||
7 :
|
||||
数字+大小写字母混合
|
||||
|
||||
1
|
||||
|
||||
ReturnVerifyCode
|
||||
boolean
|
||||
|
||||
否
|
||||
|
||||
是否返回验证码。取值:
|
||||
|
||||
true:返回。
|
||||
|
||||
false:不返回。
|
||||
|
||||
true
|
||||
|
||||
AutoRetry
|
||||
integer
|
||||
|
||||
否
|
||||
|
||||
是否自动替换签名重试(默认开启),可取值:
|
||||
|
||||
1 开启自动重试功能,开启后,在验证码有效期内,当运营商返回明确的失败状态时,允许阿里云尽可能的尝试使用其他方式发送验证码,以提升发送成功率。其他方式包括且不限于:通过其他运营商重试、更换签名重试等
|
||||
|
||||
0 不开启自动重试
|
||||
|
||||
是否自动重试
|
||||
|
||||
返回参数
|
||||
放大查看
|
||||
名称
|
||||
|
||||
类型
|
||||
|
||||
描述
|
||||
|
||||
示例值
|
||||
|
||||
object
|
||||
|
||||
AccessDeniedDetail
|
||||
string
|
||||
|
||||
访问被拒绝详细信息。
|
||||
|
||||
无
|
||||
|
||||
Message
|
||||
string
|
||||
|
||||
状态码的描述。
|
||||
|
||||
成功
|
||||
|
||||
RequestId
|
||||
string
|
||||
|
||||
请求 ID。
|
||||
|
||||
CC3BB6D2-2FDF-4321-9DCE-B38165CE4C47
|
||||
|
||||
Model
|
||||
object
|
||||
|
||||
请求结果数据。
|
||||
|
||||
VerifyCode
|
||||
string
|
||||
|
||||
验证码。
|
||||
|
||||
4232
|
||||
|
||||
RequestId
|
||||
string
|
||||
|
||||
请求 ID。
|
||||
|
||||
a3671ccf-0102-4c8e-8797-a3678e091d09
|
||||
|
||||
OutId
|
||||
string
|
||||
|
||||
外部流水号。
|
||||
|
||||
1231231313
|
||||
|
||||
BizId
|
||||
string
|
||||
|
||||
业务 ID。
|
||||
|
||||
112231421412414124123^4
|
||||
|
||||
Code
|
||||
string
|
||||
|
||||
请求状态码。返回 OK 代表请求成功。其他错误码,请参见返回码列表。
|
||||
|
||||
OK
|
||||
|
||||
Success
|
||||
boolean
|
||||
|
||||
请求是否成功。
|
||||
|
||||
true:请求成功。
|
||||
|
||||
false:请求失败。
|
||||
|
||||
true
|
||||
|
||||
示例
|
||||
正常返回示例
|
||||
|
||||
JSON格式
|
||||
|
||||
放大查看复制代码
|
||||
{
|
||||
"AccessDeniedDetail": "无",
|
||||
"Message": "成功 ",
|
||||
"RequestId": "CC3BB6D2-2FDF-4321-9DCE-B38165CE4C47",
|
||||
"Model": {
|
||||
"VerifyCode": "4232",
|
||||
"RequestId": "a3671ccf-0102-4c8e-8797-a3678e091d09",
|
||||
"OutId": "1231231313",
|
||||
"BizId": "112231421412414124123^4"
|
||||
},
|
||||
"Code": "OK",
|
||||
"Success": true
|
||||
}
|
||||
错误码
|
||||
放大查看
|
||||
HTTP status code
|
||||
|
||||
错误码
|
||||
|
||||
错误信息
|
||||
|
||||
描述
|
||||
|
||||
400 MOBILE_NUMBER_ILLEGAL The mobile number is illegal. 手机号码格式错误
|
||||
400 BUSINESS_LIMIT_CONTROL The number has exceeded the limit for the day. 触发号码天级流控
|
||||
400 FREQUENCY_FAIL Check frequency fail. 频控校验未通过
|
||||
400 INVALID_PARAMETERS parameter is not valid. 非法参数
|
||||
400 FUNCTION_NOT_OPENED You have not opened this function. 没有开通融合认证功能
|
||||
@@ -1,9 +1,22 @@
|
||||
# 短信验证码(sms)
|
||||
|
||||
> 文件:`app/integrations/sms.py` | 关联接口:[auth-sms-send](../api/auth-sms-send.md) · [auth-sms-login](../api/auth-sms-login.md) | [← 集成索引](./README.md)
|
||||
> 文件:`app/integrations/sms/`(分派器 `__init__` + `jiguang` / `aliyun` provider + `base`) | 关联接口:[auth-sms-send](../api/auth-sms-send.md) · [auth-sms-login](../api/auth-sms-login.md) | [← 集成索引](./README.md)
|
||||
|
||||
## 作用
|
||||
手机号 + 验证码登录的验证码发送 / 校验。**已接极光短信 REST**,由 `SMS_MOCK` 切 mock / real。
|
||||
手机号 + 验证码登录的验证码发送 / 校验。支持**可切换 provider**(`SMS_PROVIDER`):`jiguang`(默认,极光自管码)/ `aliyun`(阿里云号码认证托管码)。`SMS_MOCK` 另切 mock / real。
|
||||
|
||||
## 短信提供商(`SMS_PROVIDER`,可切换 + 灰度回退)
|
||||
| | `jiguang`(默认) | `aliyun` |
|
||||
|---|---|---|
|
||||
| 验证码 | **本服务生成**、极光只下发、**本地内存校验** | **阿里云生成 + 下发 + 校验**(dypns 号码认证,Mode A,核验免费) |
|
||||
| 发码 | 极光 `/v1/messages` | `SendSmsVerifyCode`(`##code##` 占位) |
|
||||
| 校验 | 比对本地存码 | `CheckSmsVerifyCode` → `PASS` / `UNKNOWN` |
|
||||
| 多 worker | ⚠️ 内存存码不共享(见已知局限) | ✅ 阿里云托管,天然共享 |
|
||||
| 防爆破 | 单码失败 `SMS_MAX_VERIFY_ATTEMPTS` 次即作废 | **同语义**(本地 per-phone 失败计数,刻意与极光一致) |
|
||||
| 单号冷却 | 本地 `SMS_SEND_INTERVAL_SEC` | 交给阿里云 `Interval` |
|
||||
| 校验降级 | 本地无网络调用 | 阿里云接口异常 → `/sms/login` 返 **503**(非 400,便于排查) |
|
||||
|
||||
`aliyun` 需在**号码认证控制台开通「融合认证」**,用系统赠送签名 + 赠送模板;配置见 `.env.example` 的 `ALIYUN_SMS_*`,SDK 为 `alibabacloud_dypnsapi20170525`。**以下章节描述 `jiguang` provider(自管码)细节**。
|
||||
|
||||
| | mock(`SMS_MOCK=true`,默认 / 开发测试) | real(`SMS_MOCK=false`,生产) |
|
||||
|---|---|---|
|
||||
|
||||
Reference in New Issue
Block a user