client_framework/docs/device_id_and_sign.md
2026-04-17 22:45:45 +08:00

2.9 KiB
Raw Blame History

设备 ID 与 fast_login 签名(宿主参考实现)

本文档描述 FunyMee 等换皮应用在实现 AuthServiceCallbacks 时采用的 getDeviceIdcomputeSign 规则,与 app_client 行为对齐,便于其它宿主复制或迁移到框架内默认实现。

框架本身仍通过接口要求宿主提供上述方法;本文档不是框架 API 说明,而是可复现的实现规范


1. 依赖(宿主 pubspec.yaml

用途 包名
AndroidSettings.Secure.ANDROID_ID android_id
iOS厂商级设备标识 device_info_plus
兜底 ID 持久化 shared_preferences
签名 MD5 cryptomd5

2. getDeviceId() 行为

defaultTargetPlatform 分支:

2.1 Android

  • 使用 android_idAndroidId().getId(),对应系统 Settings.Secure.ANDROID_ID
  • 若返回值非空,直接作为 deviceId
  • 不要device_info_plusAndroidDeviceInfo.id 当作设备 ID该字段通常为 ROM 构建号Build ID,与业务侧期望的 ANDROID_ID 不一致。

2.2 iOS

  • 使用 DeviceInfoPlugin().iosInfo,取 identifierForVendorIDFV
  • 若非空,直接作为 deviceId

2.3 其它平台或读取失败

  • 使用下文 §3 兜底 ID,保证同一安装会话内稳定、可持久化。

3. 兜底设备 IDSharedPreferences

当 Android/iOS 无法取得有效 ID或目标平台非 Android/iOS 时:

  1. 读取键名:persisted_device_id(字符串)。
  2. 若已有非空值,直接返回。
  3. 否则生成新 ID
    • 使用加密安全随机数生成 16 字节
    • Base64URL 编码后,去掉末尾 = 填充(与现有实现一致)。
  4. 写入 SharedPreferences 后返回。

注意:不同应用若使用相同键名与存储作用域,行为一致;若宿主需隔离多环境,可自行加前缀或改用独立文件名。


4. computeSign(deviceId)

与后端 fast_login 约定一致:

  • deviceId 的 UTF-8 字节MD5
  • 结果为 32 位十六进制字符串大写(例如 Dartmd5.convert(utf8.encode(deviceId)).toString().toUpperCase())。

该签名对应代理层/V2 包装中的业务字段(如文档中的 mandate / sign 等,以实际字段映射为准)。


5. 参考代码位置FunyMee

实现类:AppAuthCallbacks,文件:

FunyMee/lib/core/auth/auth_service.dart

(仅 getDeviceIdcomputeSign_persistedFallbackDeviceId 与本文档对应;其余如 onLoginSuccess 与宿主 UserState 绑定,不在此规范范围内。)