2.9 KiB
2.9 KiB
设备 ID 与 fast_login 签名(宿主参考实现)
本文档描述 FunyMee 等换皮应用在实现 AuthServiceCallbacks 时采用的 getDeviceId 与 computeSign 规则,与 app_client 行为对齐,便于其它宿主复制或迁移到框架内默认实现。
框架本身仍通过接口要求宿主提供上述方法;本文档不是框架 API 说明,而是可复现的实现规范。
1. 依赖(宿主 pubspec.yaml)
| 用途 | 包名 |
|---|---|
Android:Settings.Secure.ANDROID_ID |
android_id |
| iOS:厂商级设备标识 | device_info_plus |
| 兜底 ID 持久化 | shared_preferences |
| 签名 MD5 | crypto(md5) |
2. getDeviceId() 行为
按 defaultTargetPlatform 分支:
2.1 Android
- 使用
android_id包的AndroidId().getId(),对应系统Settings.Secure.ANDROID_ID。 - 若返回值非空,直接作为
deviceId。 - 不要用
device_info_plus的AndroidDeviceInfo.id当作设备 ID:该字段通常为 ROM 构建号(Build ID),与业务侧期望的 ANDROID_ID 不一致。
2.2 iOS
- 使用
DeviceInfoPlugin().iosInfo,取identifierForVendor(IDFV)。 - 若非空,直接作为
deviceId。
2.3 其它平台或读取失败
- 使用下文 §3 兜底 ID,保证同一安装会话内稳定、可持久化。
3. 兜底设备 ID(SharedPreferences)
当 Android/iOS 无法取得有效 ID,或目标平台非 Android/iOS 时:
- 读取键名:
persisted_device_id(字符串)。 - 若已有非空值,直接返回。
- 否则生成新 ID:
- 使用加密安全随机数生成 16 字节;
- 经 Base64URL 编码后,去掉末尾
=填充(与现有实现一致)。
- 写入 SharedPreferences 后返回。
注意:不同应用若使用相同键名与存储作用域,行为一致;若宿主需隔离多环境,可自行加前缀或改用独立文件名。
4. computeSign(deviceId)
与后端 fast_login 约定一致:
- 对
deviceId的 UTF-8 字节做 MD5; - 结果为 32 位十六进制字符串,大写(例如 Dart:
md5.convert(utf8.encode(deviceId)).toString().toUpperCase())。
该签名对应代理层/V2 包装中的业务字段(如文档中的 mandate / sign 等,以实际字段映射为准)。
5. 参考代码位置(FunyMee)
实现类:AppAuthCallbacks,文件:
FunyMee/lib/core/auth/auth_service.dart
(仅 getDeviceId、computeSign 及 _persistedFallbackDeviceId 与本文档对应;其余如 onLoginSuccess 与宿主 UserState 绑定,不在此规范范围内。)