common: - 新增 autoInit.ts 自动初始化(对齐 Android ContentProvider 模式) - 新增 configCrypto.ts 内置配置文件解密 - XuqmSDK 新增 initWithConfigFile / setUserInfo / getUserInfo - 新增 crypto-types.d.ts Web Crypto 类型声明 update: - 重写 UpdateSDK:checkAppUpdate / checkPluginUpdate / checkAndCachePlugin - 移除 checkAndPromptAppUpdate(SDK 不做 UI) - 新增插件脚手架 create-plugin.mjs - 重命名 RnUpdateInfo → PluginUpdateInfo license: - crypto.ts 支持 XUQM-CONFIG-V1 + XUQM-LICENSE-V1 双格式 - 新增 decryptConfigFile 导出 docs: - 重写 README.md - 新增 docs/SDK-API参考.md - 新增 docs/插件脚手架.md - 新增 docs/配置文件规范.md
183 行
5.3 KiB
Markdown
183 行
5.3 KiB
Markdown
# 配置文件规范
|
||
|
||
> 最后更新:2026-06-15
|
||
|
||
---
|
||
|
||
## 概述
|
||
|
||
XuqmGroup SDK 使用加密配置文件完成自动初始化,对齐 Android SDK 的 ContentProvider 模式。
|
||
|
||
**核心流程**:
|
||
|
||
1. 宿主把加密配置文件放到标准位置
|
||
2. SDK 在 common bundle 加载时自动读取、解密、初始化
|
||
3. 宿主代码零初始化调用
|
||
|
||
---
|
||
|
||
## 配置文件格式
|
||
|
||
### 加密格式
|
||
|
||
```
|
||
XUQM-CONFIG-V1.{base64urlSalt}.{base64urlIV}.{base64urlCiphertext}
|
||
```
|
||
|
||
| 部分 | 说明 |
|
||
| --------------------- | ------------------------------------------- |
|
||
| `XUQM-CONFIG-V1` | 固定 magic header |
|
||
| `base64urlSalt` | PBKDF2 盐值(16 字节,base64url 编码) |
|
||
| `base64urlIV` | AES-GCM 初始向量(12 字节,base64url 编码) |
|
||
| `base64urlCiphertext` | AES-256-GCM 密文 + 16 字节 auth tag |
|
||
|
||
### 加密参数
|
||
|
||
| 参数 | 值 |
|
||
| -------- | ------------------ |
|
||
| 算法 | AES-256-GCM |
|
||
| 密钥派生 | PBKDF2-HMAC-SHA256 |
|
||
| 迭代次数 | 120,000 |
|
||
| 密钥长度 | 256 位 |
|
||
| Auth Tag | 128 位(16 字节) |
|
||
|
||
### 解密后 JSON 结构
|
||
|
||
```json
|
||
{
|
||
"appKey": "yiwangxin",
|
||
"appName": "医网信",
|
||
"companyName": "BJCA",
|
||
"baseUrl": "https://www.51trust.com",
|
||
"serverUrl": "https://www.51trust.com",
|
||
"packageName": "cn.org.bjca.wcert.ywq",
|
||
"iosBundleId": "com.bjca.ywq",
|
||
"issuedAt": "2026-01-01T00:00:00Z",
|
||
"expiresAt": "2028-01-01T00:00:00Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| ------------- | ---- | -------------------------------- |
|
||
| `appKey` | ✅ | 应用唯一标识 |
|
||
| `appName` | ❌ | 应用名称 |
|
||
| `companyName` | ❌ | 公司名称 |
|
||
| `baseUrl` | ❌ | API 服务地址(覆盖默认值) |
|
||
| `serverUrl` | ❌ | 私有部署地址(覆盖所有服务端点) |
|
||
| `packageName` | ❌ | Android 包名(用于校验) |
|
||
| `iosBundleId` | ❌ | iOS Bundle ID |
|
||
| `issuedAt` | ❌ | 签发时间 |
|
||
| `expiresAt` | ❌ | 过期时间 |
|
||
|
||
---
|
||
|
||
## 宿主集成方式
|
||
|
||
### React Native(Metro bundler)
|
||
|
||
由于 Metro 只能 bundle JS/TS 模块,配置文件使用 `.ts` 扩展名。
|
||
|
||
**文件位置**:`src/assets/xuqm/config.xuqmconfig.ts`
|
||
|
||
```typescript
|
||
export const ENCRYPTED_CONFIG = "XUQM-CONFIG-V1.{salt}.{iv}.{ciphertext}";
|
||
```
|
||
|
||
**Metro alias**(`metro.config.js`):
|
||
|
||
```javascript
|
||
const alias = {
|
||
"@xuqm/autoinit-config": path.resolve(
|
||
projectRoot,
|
||
"src/assets/xuqm/config.xuqmconfig",
|
||
),
|
||
};
|
||
```
|
||
|
||
**Babel alias**(`babel.config.js`):
|
||
|
||
```javascript
|
||
'@xuqm/autoinit-config': './src/assets/xuqm/config.xuqmconfig'
|
||
```
|
||
|
||
**TypeScript path**(`tsconfig.json`):
|
||
|
||
```json
|
||
"@xuqm/autoinit-config": ["src/assets/xuqm/config.xuqmconfig"]
|
||
```
|
||
|
||
### Android(原生)
|
||
|
||
配置文件位置:`src/main/assets/xuqm/config.xuqm`
|
||
|
||
Android SDK 通过 ContentProvider 自动读取,无需额外配置。
|
||
|
||
### iOS(原生)
|
||
|
||
配置文件位置:`{app}/xuqm/config.xuqm`
|
||
|
||
---
|
||
|
||
## 自动初始化流程
|
||
|
||
```
|
||
common bundle 加载
|
||
→ import '@xuqm/rn-common'
|
||
→ packages/common/src/index.ts
|
||
→ import './autoInit' (副作用)
|
||
→ tryAutoInit()
|
||
→ require('@xuqm/autoinit-config')
|
||
→ Metro 解析 alias → 宿主 config.xuqmconfig.ts
|
||
→ XuqmSDK.initWithConfigFile(encrypted)
|
||
→ configCrypto.decryptConfigFile(encrypted)
|
||
→ PBKDF2 派生密钥
|
||
→ AES-256-GCM 解密
|
||
→ initializeFromLicense(decrypted)
|
||
→ configureHttp(baseUrl || serverUrl)
|
||
→ markInitialized()
|
||
```
|
||
|
||
### 失败处理
|
||
|
||
对齐 Android SDK 的 `runCatching + Log.w` 行为:
|
||
|
||
- 配置文件不存在 → 静默跳过
|
||
- 解密失败 → 静默跳过
|
||
- SDK 保持未初始化状态
|
||
- `awaitInitialization()` 会超时
|
||
- 不崩溃、不阻塞 app 启动
|
||
|
||
---
|
||
|
||
## 降级机制
|
||
|
||
如果自动初始化失败,宿主可以手动调用:
|
||
|
||
```typescript
|
||
import { XuqmSDK } from "@xuqm/rn-common";
|
||
|
||
// 使用默认 URL 初始化
|
||
XuqmSDK.init({ appKey: "yiwangxin", debug: __DEV__ });
|
||
```
|
||
|
||
---
|
||
|
||
## 安全注意事项
|
||
|
||
1. **不要提交解密后的明文配置**到版本控制
|
||
2. **不要在日志中打印**配置文件内容或解密后的数据
|
||
3. 配置文件的 `appKey` 用于 API 调用,**不要硬编码**在业务代码中
|
||
4. `serverUrl` 字段会覆盖所有服务端点,确保指向正确的环境
|
||
|
||
---
|
||
|
||
## 与 Android SDK 的对齐
|
||
|
||
| 环节 | Android SDK | RNSDK |
|
||
| ------------ | -------------------------- | --------------------------------------------- |
|
||
| 配置文件位置 | `assets/xuqm/config.xuqm` | `src/assets/xuqm/config.xuqmconfig.ts` |
|
||
| 自动初始化 | ContentProvider.onCreate() | common 包 import 时 autoInit |
|
||
| 解密 | ConfigFileCrypto (Java) | configCrypto (JS + react-native-quick-crypto) |
|
||
| 失败处理 | runCatching + Log.w | try/catch + 静默跳过 |
|
||
| 服务端点覆盖 | configurePrivateServer() | initializeFromLicense(serverUrl) |
|