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

借助 Credential Manager 的恢复凭据功能,用户可以在设置新设备时恢复其应用账号。此 API 推出了开发者预览版,适用于所有符合以下条件的设备:搭载 Android 9 或更高版本,且 Google Play 服务 (GMS) Core 版本为 242200000 或更高。恢复凭据功能的好处包括:

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

工作原理

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

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

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

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

实现

您可以通过 Credential Manager Jetpack 库使用 Restore Credentials 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. 恢复密钥是一次性凭据吗?

不是,恢复密钥不是一次性凭据。Credential Manager 是无状态的,不知道用户活动,因此无法自动删除已使用的密钥。

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

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

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

是的。此功能专门用于新 Android 设备的初始设置,因为它与系统的备份和恢复功能直接关联。

问题 4. 我能否使用恢复凭据功能在已登录同一 Google 账号的任何设备上实现用户静默登录?

不能,恢复凭据功能的用途不是实现跨设备常规登录。该功能仅适用于一种特定情形:用户通过恢复旧设备的备份数据来设置新设备。两部设备必须关联到同一 Google 账号,才能成功完成此一次性恢复流程。

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

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

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

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

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

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

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

问题 8. 不在清单中将 allowBackup 设置为 true,也能使用恢复凭据功能吗?

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

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

恢复凭据功能设计为一次仅与一个账号搭配使用。