refactor: 融合认证 schemeCode 按平台拆分为独立环境变量
不同端(Android/iOS/Harmony)在阿里云控制台使用不同的方案 Code, 单一 ALIYUN_FUSION_SCHEME_CODE 无法满足多端需求。改为按平台映射 三个独立环境变量,providers 端点也按平台精确判断可用性。 同步更新 API 文档:补充 fusion/token 请求参数表和 Harmony 平台支持。
This commit is contained in:
parent
b6fc6c5a9b
commit
7682bb2ae7
@ -27,7 +27,9 @@ OSS_REGION=
|
|||||||
# RAM 子用户需授予 AliyunDypnsFullAccess 权限
|
# RAM 子用户需授予 AliyunDypnsFullAccess 权限
|
||||||
ALIYUN_ACCESS_KEY_ID=
|
ALIYUN_ACCESS_KEY_ID=
|
||||||
ALIYUN_ACCESS_KEY_SECRET=
|
ALIYUN_ACCESS_KEY_SECRET=
|
||||||
ALIYUN_FUSION_SCHEME_CODE=
|
ALIYUN_FUSION_SCHEME_CODE_ANDROID=
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_IOS=
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_HARMONY=
|
||||||
|
|
||||||
# Huawei IAP (Phase 1c)
|
# Huawei IAP (Phase 1c)
|
||||||
HUAWEI_IAP_URL=
|
HUAWEI_IAP_URL=
|
||||||
|
|||||||
@ -25,6 +25,15 @@ OSS_ACCESS_KEY_SECRET=
|
|||||||
OSS_BUCKET=duoqi-assets
|
OSS_BUCKET=duoqi-assets
|
||||||
OSS_REGION=oss-cn-hangzhou
|
OSS_REGION=oss-cn-hangzhou
|
||||||
|
|
||||||
|
# Alibaba Cloud Fusion Auth
|
||||||
|
# 阿里云号码认证服务,用于手机号一键登录和短信验证码登录
|
||||||
|
# RAM 子用户需授予 AliyunDypnsFullAccess 权限
|
||||||
|
ALIYUN_ACCESS_KEY_ID=
|
||||||
|
ALIYUN_ACCESS_KEY_SECRET=
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_ANDROID=
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_IOS=
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_HARMONY=
|
||||||
|
|
||||||
# Huawei IAP
|
# Huawei IAP
|
||||||
HUAWEI_IAP_URL=https://subscr-drcn.iap.hicloud.com
|
HUAWEI_IAP_URL=https://subscr-drcn.iap.hicloud.com
|
||||||
HUAWEI_MERCHANT_ID=
|
HUAWEI_MERCHANT_ID=
|
||||||
|
|||||||
@ -274,9 +274,24 @@
|
|||||||
认证:无
|
认证:无
|
||||||
限流:10 次/分钟
|
限流:10 次/分钟
|
||||||
|
|
||||||
用途:获取阿里云融合认证 SDK 鉴权 Token。客户端在初始化 SDK 前调用此接口。
|
用途:获取阿里云融合认证 SDK 鉴权 Token。客户端在初始化 SDK 前调用此接口。`schemeCode` 和 `durationSeconds` 由服务端配置,不暴露给客户端。
|
||||||
|
|
||||||
请求:无请求体(schemeCode 从服务端配置读取)。
|
请求:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| `platform` | `"Android"` \| `"iOS"` \| `"Harmony"` | 是 | 客户端平台 |
|
||||||
|
| `packageName` | string | Android 必填 | App 包名 |
|
||||||
|
| `packageSign` | string | Android 必填 | App 包签名(MD5,去冒号小写) |
|
||||||
|
| `bundleId` | string | iOS 必填 | App Bundle ID |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"platform": "Android",
|
||||||
|
"packageName": "com.example.app",
|
||||||
|
"packageSign": "a1b2c3d4e5f6..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
响应:
|
响应:
|
||||||
|
|
||||||
@ -297,7 +312,7 @@
|
|||||||
"success": false,
|
"success": false,
|
||||||
"data": null,
|
"data": null,
|
||||||
"error": {
|
"error": {
|
||||||
"code": "UNAUTHORIZED",
|
"code": "SERVICE_UNAVAILABLE",
|
||||||
"message": "Fusion auth is not configured on the server"
|
"message": "Fusion auth is not configured on the server"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ const fusionVerifySchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fusionTokenSchema = z.object({
|
const fusionTokenSchema = z.object({
|
||||||
platform: z.enum(['Android', 'iOS']),
|
platform: z.enum(['Android', 'iOS', 'Harmony']),
|
||||||
packageName: z.string().optional(),
|
packageName: z.string().optional(),
|
||||||
packageSign: z.string().optional(),
|
packageSign: z.string().optional(),
|
||||||
bundleId: z.string().optional(),
|
bundleId: z.string().optional(),
|
||||||
@ -78,11 +78,20 @@ const PROVIDER_METADATA: Record<string, { name: string; type: ProviderEntry['typ
|
|||||||
const CREDENTIAL_PROVIDERS = new Set(['fusion', 'phone_sms', 'huawei', 'apple']);
|
const CREDENTIAL_PROVIDERS = new Set(['fusion', 'phone_sms', 'huawei', 'apple']);
|
||||||
const DB_TOGGLE_PROVIDERS = new Set(['wechat', 'qq']);
|
const DB_TOGGLE_PROVIDERS = new Set(['wechat', 'qq']);
|
||||||
|
|
||||||
function isCredentialConfigured(providerId: string): boolean {
|
function isCredentialConfigured(providerId: string, platform?: Platform): boolean {
|
||||||
switch (providerId) {
|
switch (providerId) {
|
||||||
case 'fusion':
|
case 'fusion':
|
||||||
case 'phone_sms':
|
case 'phone_sms': {
|
||||||
return !!(config.ALIYUN_ACCESS_KEY_ID && config.ALIYUN_ACCESS_KEY_SECRET && config.ALIYUN_FUSION_SCHEME_CODE);
|
const hasCredentials = !!(config.ALIYUN_ACCESS_KEY_ID && config.ALIYUN_ACCESS_KEY_SECRET);
|
||||||
|
if (!hasCredentials) return false;
|
||||||
|
if (!platform) return true;
|
||||||
|
const schemeCodeMap: Record<Platform, string | undefined> = {
|
||||||
|
android: config.ALIYUN_FUSION_SCHEME_CODE_ANDROID,
|
||||||
|
ios: config.ALIYUN_FUSION_SCHEME_CODE_IOS,
|
||||||
|
harmony: config.ALIYUN_FUSION_SCHEME_CODE_HARMONY,
|
||||||
|
};
|
||||||
|
return !!schemeCodeMap[platform];
|
||||||
|
}
|
||||||
case 'huawei':
|
case 'huawei':
|
||||||
return !!(config.HUAWEI_CLIENT_ID && config.HUAWEI_CLIENT_SECRET);
|
return !!(config.HUAWEI_CLIENT_ID && config.HUAWEI_CLIENT_SECRET);
|
||||||
case 'apple':
|
case 'apple':
|
||||||
@ -109,7 +118,7 @@ function buildProviderList(platform: Platform, dbToggles: Map<string, boolean>):
|
|||||||
if (!PLATFORM_AVAILABILITY[id]?.includes(platform)) continue;
|
if (!PLATFORM_AVAILABILITY[id]?.includes(platform)) continue;
|
||||||
|
|
||||||
const enabled = CREDENTIAL_PROVIDERS.has(id)
|
const enabled = CREDENTIAL_PROVIDERS.has(id)
|
||||||
? isCredentialConfigured(id)
|
? isCredentialConfigured(id, platform)
|
||||||
: DB_TOGGLE_PROVIDERS.has(id)
|
: DB_TOGGLE_PROVIDERS.has(id)
|
||||||
? (dbToggles.get(id) ?? false)
|
? (dbToggles.get(id) ?? false)
|
||||||
: false;
|
: false;
|
||||||
|
|||||||
@ -29,11 +29,17 @@ function getClient() {
|
|||||||
return clientInstance;
|
return clientInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function requireSchemeCode(): string {
|
function requireSchemeCode(platform: string): string {
|
||||||
if (!config.ALIYUN_FUSION_SCHEME_CODE) {
|
const schemeCodeMap: Record<string, string | undefined> = {
|
||||||
throw new UnauthorizedError('Fusion auth scheme code is not configured');
|
Android: config.ALIYUN_FUSION_SCHEME_CODE_ANDROID,
|
||||||
|
iOS: config.ALIYUN_FUSION_SCHEME_CODE_IOS,
|
||||||
|
Harmony: config.ALIYUN_FUSION_SCHEME_CODE_HARMONY,
|
||||||
|
};
|
||||||
|
const schemeCode = schemeCodeMap[platform];
|
||||||
|
if (!schemeCode) {
|
||||||
|
throw new UnauthorizedError(`Fusion auth scheme code not configured for platform: ${platform}`);
|
||||||
}
|
}
|
||||||
return config.ALIYUN_FUSION_SCHEME_CODE;
|
return schemeCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getFusionAuthToken(options: {
|
export async function getFusionAuthToken(options: {
|
||||||
@ -43,7 +49,7 @@ export async function getFusionAuthToken(options: {
|
|||||||
bundleId?: string;
|
bundleId?: string;
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
const client = getClient();
|
const client = getClient();
|
||||||
const schemeCode = requireSchemeCode();
|
const schemeCode = requireSchemeCode(options.platform);
|
||||||
|
|
||||||
const request = new $Dypnsapi20170525.GetFusionAuthTokenRequest({
|
const request = new $Dypnsapi20170525.GetFusionAuthTokenRequest({
|
||||||
schemeCode,
|
schemeCode,
|
||||||
|
|||||||
@ -18,7 +18,9 @@ const envSchema = z.object({
|
|||||||
APPLE_BUNDLE_ID: z.string().optional(),
|
APPLE_BUNDLE_ID: z.string().optional(),
|
||||||
ALIYUN_ACCESS_KEY_ID: z.string().optional(),
|
ALIYUN_ACCESS_KEY_ID: z.string().optional(),
|
||||||
ALIYUN_ACCESS_KEY_SECRET: z.string().optional(),
|
ALIYUN_ACCESS_KEY_SECRET: z.string().optional(),
|
||||||
ALIYUN_FUSION_SCHEME_CODE: z.string().optional(),
|
ALIYUN_FUSION_SCHEME_CODE_ANDROID: z.string().optional(),
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_IOS: z.string().optional(),
|
||||||
|
ALIYUN_FUSION_SCHEME_CODE_HARMONY: z.string().optional(),
|
||||||
PORT: z.coerce.number().default(3000),
|
PORT: z.coerce.number().default(3000),
|
||||||
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
||||||
LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),
|
LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user