f161d07615
新增 aliyun_onekey(Dypnsapi GetMobile 换号,无 RSA)+ oneclick 门面(按 provider 分派 jiguang/aliyun);jverify-login 与微信绑号两处换号改走门面 + JverifyLoginRequest 加 provider 字段 + ALIYUN_ONEKEY 配置。新增 15 单测(aliyun_onekey/oneclick/端点),微信绑号回归修 2 处桩。真机端到端验证通过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
42 lines
1.8 KiB
Python
42 lines
1.8 KiB
Python
"""一键登录换号门面:按 provider 分派到极光/阿里云, 统一异常与手机号脱敏。
|
|
|
|
为什么要门面:一键登录 token 与「拉授权页的那家 SDK」强绑定 —— 客户端用极光 SDK 拉的
|
|
token 只能用极光换号, 阿里云的只能用阿里云换号。所以 provider 必须由客户端如实上报, 服务端
|
|
按此分派、不能猜。老客户端不带 provider → 默认极光(向后兼容)。
|
|
|
|
用法(api 层):
|
|
from app.integrations import oneclick
|
|
try:
|
|
phone = oneclick.verify_and_get_phone(req.provider, req.login_token)
|
|
except oneclick.OneClickError as e:
|
|
raise HTTPException(502, ...) from e
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
# 用「模块属性访问」而非 from ... import 函数:保证 monkeypatch 各家实现时门面能拿到替身。
|
|
from app.integrations import aliyun_onekey, jiguang
|
|
from app.integrations.jiguang import mask_phone # 复用脱敏, 从门面转出供 api 层用
|
|
|
|
__all__ = ["OneClickError", "mask_phone", "verify_and_get_phone"]
|
|
|
|
PROVIDER_JIGUANG = "jiguang"
|
|
PROVIDER_ALIYUN = "aliyun"
|
|
|
|
|
|
class OneClickError(Exception):
|
|
"""换号失败统一异常(不区分厂商), api 层 catch → 502。"""
|
|
|
|
|
|
def verify_and_get_phone(provider: str, login_token: str) -> str:
|
|
"""按 provider 换取明文手机号。失败(任一厂商)抛 OneClickError。
|
|
|
|
provider 大小写不敏感;空 / 未知值兜底走极光(主家), 不因客户端传错值而拒登。
|
|
"""
|
|
p = (provider or PROVIDER_JIGUANG).strip().lower()
|
|
try:
|
|
if p == PROVIDER_ALIYUN:
|
|
return aliyun_onekey.verify_and_get_phone(login_token)
|
|
return jiguang.verify_and_get_phone(login_token)
|
|
except (jiguang.JiguangError, aliyun_onekey.AliyunOneClickError) as e:
|
|
raise OneClickError(f"[{p}] {e}") from e
|