在设置新设备时恢复应用凭据

借助凭据管理器的恢复凭据功能,用户可以在设置新设备时恢复其应用账号。此 API 处于开发者预览状态,适用于所有搭载 Android 9 或更高版本且 Google Play 服务 (GMS) Core 版本为 242200000 或更高版本的设备。恢复凭据功能的优势包括:

  • 顺畅的用户体验:用户可以恢复其应用账号,而无需手动登录每个应用。
  • 提高用户互动度:如果用户在设置新设备时可以恢复其账号,则更有可能继续使用您的应用。
  • 减少开发工作量:恢复凭据功能已与 Credential Manager 集成,因此已支持通行密钥的开发者可以添加凭据恢复功能。

工作原理

您可以使用“恢复凭据”来创建、获取和清除相关凭据。

  1. 创建恢复凭据:当用户登录您的应用时,创建与其账号关联的恢复凭据。此凭据存储在本地,如果用户已启用 Google 备份且端到端加密可用,则会同步到云端(应用可以选择不同步到云端)
  2. 获取恢复凭据:当用户设置新设备时,您的应用可以向 Credential Manager 请求恢复凭据。这样一来,您就可以自动让用户登录,而无需任何额外输入。
  3. 清除恢复凭据:当用户从您的应用中退出账号时,您应删除关联的恢复凭据。

“恢复凭据”功能可以与已实现通行密钥的后端系统顺畅集成。这种兼容性源于以下事实:通行密钥和恢复密钥(“恢复凭据”功能使用的凭据类型)都遵循相同的底层技术规范。这种对齐可确保“恢复凭据”流程能够有效地检索和恢复存储在已启用通行密钥的系统中的用户凭据,从而在不同平台和身份验证方法中提供一致且用户友好的体验。

Credential Manager 底部动作条
图 1. 图表:使用恢复凭据将应用数据恢复到新设备,包括创建凭据、启动恢复流程和自动用户登录

实现

您可以通过 Credential Manager Jetpack 库使用“恢复凭据”API。要开始,请执行以下步骤:

  1. 将 Credential Manager 依赖项添加到项目中。

    // build.gradle.kts
    implementation("androidx.credentials:credentials:1.5.0-alpha03")
    
  2. 创建一个 CreateRestoreCredentialRequest 对象。

  3. CredentialManager 对象调用 createCredential() 方法。

    val credentialManager = CredentialManager.create(context)
    
    // On a successful authentication create a Restore Key
    // Pass in the context and CreateRestoreCredentialRequest object
    val response = credentialManager.createCredential(context, createRestoreRequest)
    

    生成的恢复凭据是一种 WebAuthn 凭据,称为恢复密钥

  4. 当用户设置新设备时,请对 CredentialManager 对象调用 getCredential() 方法。

    // Fetch the Authentication JSON from server
    val authenticationJson = fetchAuthenticationJson()
    
    // Create the GetRestoreCredentialRequest object
    val options = GetRestoreCredentialOption(authenticationJson)
    val getRequest = GetCredentialRequest(listOf(options))
    
    // The restore key can be fetched in two scenarios to
    // 1. On the first launch of app on the device, fetch the Restore Key
    // 2. In the onRestore callback (if the app implements the Backup Agent)
    val response = credentialManager.getCredential(context, getRequest)
    
  5. 当用户从您的应用中退出账号时,请对 CredentialManager 对象调用 clearCredentialState() 方法。

    // Create a ClearCredentialStateRequest object
    val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)
    
    // On user log-out, clear the restore key
    val response = credentialManager.clearCredentialState(clearRequest)
    

如果您使用的是备份代理,请在 onRestore 回调中执行 getCredential 部分。这样可确保在恢复应用数据后立即恢复应用的凭据。

常见问题解答

问题 1. 恢复密钥和通行密钥有何区别?

恢复密钥的功能与通行密钥类似,但专门用于在新设备上恢复账号。当您使用 Google 密码管理工具等密码管理工具进行身份验证时,系统会显示可用的通行密钥和密码,但不会显示恢复密钥,因为恢复密钥不适用于常规登录。

问题 2. 恢复密钥是否是一次性凭据?

不是,恢复密钥不是一次性凭据。凭据管理器是无状态的,不知道用户活动,因此无法在使用后自动删除密钥。

仅在以下情况下会移除恢复密钥:

  • 系统级操作:用户卸载应用或清除应用数据。
  • 应用级调用:您可以在应用的代码中处理用户退出登录时,通过调用 CredentialManager#clearCredentialState() 以编程方式删除密钥。

问题 3. “恢复凭据”功能是否仅适用于新设备?

可以。此功能专为新 Android 设备在初始设置时使用而设计,因为它直接与系统的备份和恢复功能相关联。

问题 4. 我可以使用 Restore Credentials 在已登录同一 Google 账号的任何设备上以静默方式登录用户吗?

否,“恢复凭据”功能并非旨在用于在各种设备上进行常规登录。它仅在一种特定情况下有效:当用户通过恢复旧设备的备份来设置新设备时。两部设备必须关联到同一 Google 账号,才能成功完成此一次性恢复流程。

问题 5. 我的组织有一个主应用和多个子应用。是否可以为所有这些应用恢复一个密钥?

不能。恢复密钥与应用的唯一软件包名称相关联。由于您的主应用和每个子应用都有不同的软件包名称,因此您需要为每个应用分别创建恢复密钥。

问题 6. 是否需要通行密钥才能为用户账号创建恢复密钥?

不需要,通行密钥不是必需的。创建恢复密钥的功能与用户的登录方法无关。其目的是保存用户当前的已验证状态。只要用户已主动登录您的应用,您就可以为其生成恢复密钥。

问题 7. 用户能否删除恢复密钥?

否,用户无法直接控制恢复密钥。应用逻辑负责管理恢复密钥。

为了安全起见,我们建议应用在用户每次退出时自动删除密钥。这样可确保用户下次在同一设备上打开应用时,系统会正确将其退出账号,并提示其重新登录。

问题 8. 我可以在清单中不将 allowBackup 设置为 true 的情况下使用 Restore Credentials 吗?

可以,“恢复凭据”功能无论 allowBackup 是否设置为 true 都可以正常运行。

问题 9. 如果用户在同一应用中登录了多个账号,恢复凭据功能会如何运作?

恢复凭据功能旨在一次仅与一个账号搭配使用。