restore-credentials
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFundamentals
基础概述
The objective is to implement the Restore Credentials feature through the
Android Credential Manager API (). This allows apps that
use or are integrating Credential Manager to silently log users back in when
they restore their app on a new device. Restore Credentials operates
independently of the app's primary authentication method (passwords, passkeys,
federated sign-in) and requires no UI changes to existing sign-in flows.
androidx.credentials本内容旨在通过Android Credential Manager API()实现Restore Credentials功能。这使得使用或集成Credential Manager的应用,在用户将应用恢复到新设备时,能够自动为用户静默登录。Restore Credentials独立于应用的主要认证方式(密码、通行密钥、联合登录),无需对现有登录流程的UI进行任何修改。
androidx.credentialsScope
适用范围
Crucial: This skill focuses exclusively on the Android client-side
integration. It does not implement the server-side cryptographic
validation logic. The developer must be reminded of this and the
Points to inform the developer about after implementation is done.
重要提示: 本技能仅聚焦于Android客户端集成,不实现服务端的加密验证逻辑。必须提醒开发者这一点,并在完成实现后告知其需要注意的要点。
Implementation Guidelines
实施指南
When instructed to implement Restore Credentials on a developer's application,
remember the following:
- Before the implementation, you MUST read and understand the Two-Tier Restoration Architecture and review the DOs and DON'Ts.
- After the implementation, you MUST present the developer with the Backend Guidelines as a reminder for their backend setup. It is important that you remind the developer that they still have to implement the backend.
当被要求在开发者的应用中实现Restore Credentials时,请牢记以下事项:
- 在开始实施前,你必须阅读并理解双层恢复架构,同时查看注意事项(DOs and DON'Ts)。
- 完成实施后,你必须向开发者展示后端指南,提醒他们进行后端配置。务必告知开发者仍需自行实现后端功能。
Two-Tier Restoration Architecture
双层恢复架构
To enable a resilient sign-in experience, retrieve credentials through a
two-tier architecture:
- Tier 1 (Primary - Background): Executes automatically during device setup using the app's callback. This provides an invisible restoration before the user opens the app for the first time, allowing background sync and notification delivery.
BackupAgent.onRestoreFinished() - Tier 2 (Secondary - Foreground): Runs in the Launcher to catch failovers if background restoration didn't complete (example: dropped network, delayed restoration) or if
Activity.onCreate()is disabled.allowBackup
If in the manifest is set to true, implement both. Otherwise, only
implement tier 2 (Foreground Restoration). Do NOT change the value of
in the manifest.
allowBackupallowBackup为实现可靠的登录体验,请通过双层架构获取凭证:
- 第一层(主层 - 后台): 在设备设置期间,通过应用的回调自动执行。这能在用户首次打开应用前完成隐形恢复,支持后台同步和通知推送。
BackupAgent.onRestoreFinished() - 第二层(次层 - 前台): 在启动器中运行,用于捕获后台恢复未完成的情况(例如:网络中断、恢复延迟)或
Activity.onCreate()被禁用的场景。allowBackup
如果清单文件中的设置为true,则需同时实现两层架构;否则,仅实现第二层(前台恢复)。请勿修改清单文件中的值。
allowBackupallowBackupDOs and DON'Ts
注意事项(DOs and DON'Ts)
DO:
- Do check for the value of allowBackup to determine what you have to implement.
AndroidManifest.xml - Do implement a fallback for createCredential: always try calling it first with set to true. If an
isCloudBackupEnabledis thrown, catch it and retry the call withE2eeUnavailableExceptionset toisCloudBackupEnabled.false - Do implement a (subclass of
BackupAgent) ifandroid.app.backup.BackupAgentis true in the manifest.allowBackup - Call when the user signs out. This is a mandatory security measure to log the user out fully.
clearCredentialState() - Do attempt to get the restore key on the first launch of the app on a new device and also within the callback if your app uses it.
BackupAgent.onRestoreFinished() - Do ensure that a restore credential is created even if the user is already logged in.
- Do ensure that the credential retrieval and login in is performed synchronously (for example using
onRestoreFinished()).runBlocking - Do restore notifications in the if your app uses them. (For example capture and send FCM token to backend)
BackupAgent - Do ensure that if you implement mock network requests or stubs, you replace all placeholders with valid, properly formatted JSON payloads for the credential requests.
- Do encapsulate credential creation and retrieval into their own dedicated functions. Because credential creation must be called in multiple places (sign-up, sign-in) and retrieval across multiple tiers (and Launcher
BackupAgent), this prevents code duplication.Activity - Do remind the developer of the critical guidelines for implementing the backend once you're done with the implementation.
- Do generate a separate restore key for each application if the organization has multiple apps with different package names, as a restore key is tied to a unique application package name.
DON'T:
- DON'T change the value of in
allowBackup. Restore Credentials functionality is not affected by the allowBackup setting, meaning the user will still be automatically logged in when a Restore Credential exists, even ifAndroidManifest.xmlis false.allowBackup - DON'T implement a if
BackupAgentisallowBackupinfalse.AndroidManifest.xml - DON'T assume the credential stored in the to be of type
GetCredentialResponse. It has typePublicKeyCredential.RestoreCredential - DON'T chain with any other
GetRestoreCredentialOptionin the construction of aCredentialOption.GetCredentialRequest - DON'T assume or the Android system will automatically delete a restore key when a user signs out of the app. You must explicitly call
CredentialManagerwith aclearCredentialStateofClearCredentialStateRequest.TYPE_CLEAR_RESTORE_CREDENTIAL - DON'T remove any existing calls to . A
clearCredentialState()without a type specified only clears all NON-restore credentials.ClearCredentialStateRequest
应当执行:
- 检查中的allowBackup值,以确定需要实现的内容。
AndroidManifest.xml - 为createCredential实现回退逻辑:始终先尝试将设为true调用该方法。如果抛出
isCloudBackupEnabled,捕获该异常并将E2eeUnavailableException设为isCloudBackupEnabled后重试。false - 如果清单文件中的allowBackup为true,实现(继承自
BackupAgent)。android.app.backup.BackupAgent - 用户退出登录时调用,这是确保用户完全退出的强制性安全措施。
clearCredentialState() - 在新设备上首次启动应用时尝试获取恢复密钥;如果应用使用了,还需在
BackupAgent回调中执行该操作。BackupAgent.onRestoreFinished() - 确保即使用户已登录,也会创建恢复凭证。
- 确保中的凭证获取和登录操作同步执行(例如使用
onRestoreFinished())。runBlocking - 如果应用使用通知功能,需在中恢复通知(例如捕获并将FCM令牌发送到后端)。
BackupAgent - 如果实现模拟网络请求或存根,需将所有占位符替换为格式正确的有效JSON负载,用于凭证请求。
- 将凭证创建和获取逻辑封装到独立的专用函数中。由于凭证创建需要在多个场景(注册、登录)调用,而获取操作需要在多个层级(和启动器
BackupAgent)执行,这样可以避免代码重复。Activity - 完成客户端实现后,提醒开发者注意后端实施的关键指南。
- 如果组织拥有多个不同包名的应用,需为每个应用生成独立的恢复密钥,因为恢复密钥与唯一的应用包名绑定。
禁止执行:
- 请勿修改中的
AndroidManifest.xml值。Restore Credentials功能不受allowBackup设置影响,这意味着即使allowBackup为false,只要存在恢复凭证,用户仍会自动登录。allowBackup - 如果中的allowBackup为
AndroidManifest.xml,请勿实现false。BackupAgent - 请勿假设中存储的凭证类型为
GetCredentialResponse,其实际类型为PublicKeyCredential。RestoreCredential - 在构建时,请勿将
GetCredentialRequest与其他GetRestoreCredentialOption链式调用。CredentialOption - 请勿假设Credential Manager或Android系统会在用户退出应用时自动删除恢复密钥。你必须显式调用并传入类型为
clearCredentialState的TYPE_CLEAR_RESTORE_CREDENTIAL。ClearCredentialStateRequest - 请勿移除任何现有的调用。未指定类型的
clearCredentialState()仅会清除所有非恢复凭证。ClearCredentialStateRequest
Implementation Guide
实施步骤
Implement the Android client-side code by using the following guide. Follow it
step-by-step and don't implement any backend functionality, only remind
the user of the Backend Guidelines once you're done.
按照以下指南实现Android客户端代码,请逐步执行,不要实现任何后端功能,仅需在完成后提醒用户查看后端指南。
Version compatibility
版本兼容性
Credential Manager's Restore Credentials works on devices running Android 9 and
higher, Google Play services (GMS) core version 24220000 or higher, and version
1.5.0 or higher of the library.
androidx.credentialsCredential Manager的Restore Credentials功能适用于运行Android 9及以上版本、Google Play服务(GMS)核心版本24220000及以上,以及库1.5.0及以上版本的设备。
androidx.credentialsPrerequisites
前置条件
Set up a relying party server similar to the server for passkeys. If
you already have a server set up to handle authentication with passkeys,
use the same server-side implementation for restore keys.
[!NOTE] Note: While the server-side implementation is the same for passkeys and restore keys, your client-side app can support restore keys without supporting passkeys. Because restore keys work independently of the authentication method in your app (for example, passwords or Sign in with Google), you don't need to make any additional changes to the existing authentication methods in your app's code.
搭建一个依赖方服务器,其功能与通行密钥的服务器类似。如果已经搭建了处理通行密钥认证的服务器,可使用相同的服务端实现来处理恢复密钥。
[!NOTE] 注意: 虽然通行密钥和恢复密钥的服务端实现相同,但客户端应用可以在不支持通行密钥的情况下支持恢复密钥。由于恢复密钥独立于应用中的认证方式(例如密码或Google登录),你无需对应用代码中现有的认证方式进行任何额外修改。
Dependencies
依赖配置
Add the following dependencies to your app module's file:
build.gradle将以下依赖项添加到应用模块的文件中:
build.gradleKotlin
Kotlin
kotlin
dependencies {
implementation("androidx.credentials:credentials:1.7.0-alpha03")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
}kotlin
dependencies {
implementation("androidx.credentials:credentials:1.7.0-alpha03")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
}Groovy
Groovy
groovy
dependencies {
implementation "androidx.credentials:credentials:1.7.0-alpha03"
implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha03"
}Restore Credentials is available from version 1.5.0 and higher of the
androidx.credentials library. However, it's recommended to use the latest stable
versions of the dependencies where possible.
[!NOTE] Note: The Restore Credentials feature works regardless of whetheris set in theallowBackup.manifest
groovy
dependencies {
implementation "androidx.credentials:credentials:1.7.0-alpha03"
implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha03"
}Restore Credentials功能从androidx.credentials库1.5.0版本开始可用,但建议尽可能使用最新的稳定版本依赖。
[!NOTE] 注意: Restore Credentials功能的可用性与清单文件中是否设置无关。allowBackup
Overview
流程概述
- Create a restore key: To create a restore key, complete the following steps:
- Instantiate Credential Manager: Create a object.
CredentialManager - Get credential creation options from the app server: Send the client app the details required to create the restore key from your app server.
- Create the restore key: Create a restore key for the user's account if the user is signed in to your app.
- Handle the credential creation response: Send the credentials from your client app to your app server for processing, and handle any exceptions.
- Instantiate Credential Manager: Create a
- Sign in with a restore key: To sign in with a restore key, complete the following steps:
- Get credential retrieval options from the app server: Send the client app the details required to retrieve the restore key from your app server.
- Get the restore key: Request the restore key from Credential Manager when the user sets up a new device. This lets the user sign in without additional input.
- Handle the credential retrieval response: Send the restore key from the client app to the app server to sign in the user.
- Delete a restore key.
- 创建恢复密钥:创建恢复密钥需完成以下步骤:
- 实例化Credential Manager:创建对象。
CredentialManager - 从应用服务器获取凭证创建选项:从应用服务器获取创建恢复密钥所需的详细信息并发送给客户端应用。
- 创建恢复密钥:如果用户已登录应用,为其账户创建恢复密钥。
- 处理凭证创建响应:将客户端应用的凭证发送到应用服务器进行处理,并处理可能出现的异常。
- 实例化Credential Manager:创建
- 使用恢复密钥登录:使用恢复密钥登录需完成以下步骤:
- 从应用服务器获取凭证检索选项:从应用服务器获取检索恢复密钥所需的详细信息并发送给客户端应用。
- 获取恢复密钥:用户设置新设备时,向Credential Manager请求恢复密钥,实现用户无需额外输入即可登录。
- 处理凭证检索响应:将客户端应用的恢复密钥发送到应用服务器,完成用户登录。
- 删除恢复密钥。
Create a restore key
创建恢复密钥
Your app should cover all cases of a user signing in to ensure active users have
a restore key created. Create the restore key in the following scenarios:
- If the user is signed in and a restore key isn't already created (such as in the method for the main
onCreate).Activity - When the user is signing in or completing a new account registration flow.
To optimize performance and avoid the overhead of creating or checking for a
restore credential on every single login, set a flag or a credential
creation timestamp in local storage, such as , to
track whether the key has already been created.
booleanhas_synced_restore_credential[!NOTE] Note: A restore key is tied to an application's unique package name. If your organization's main app and sub-apps have different package names, create a separate restore key for each app.
应用需覆盖用户登录的所有场景,确保活跃用户都能创建恢复密钥。请在以下场景中创建恢复密钥:
- 用户已登录但尚未创建恢复密钥时(例如在主的
Activity方法中)。onCreate - 用户登录或完成新账户注册流程时。
为优化性能,避免每次登录都创建或检查恢复凭证的开销,可在本地存储中设置一个布尔标志或凭证创建时间戳,例如,用于跟踪密钥是否已创建。
has_synced_restore_credential[!NOTE] 注意: 恢复密钥与应用的唯一包名绑定。如果组织的主应用和子应用具有不同的包名,需为每个应用创建独立的恢复密钥。
Instantiate Credential Manager
实例化Credential Manager
Use your app's activity context to instantiate a object.
CredentialManager// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)使用应用的活动上下文实例化对象。
CredentialManager// 使用应用或活动上下文实例化CredentialManager的客户端实例
private val credentialManager = CredentialManager.create(context)Get credential creation options from your app server
从应用服务器获取凭证创建选项
Use a FIDO-compliant library in your app server to send your client app the
information required to create the restore credential, such as information about
the user, the app, and additional configuration properties. For more information
about the server-side implementation, see Server-side
guidance.
在应用服务器中使用符合FIDO标准的库,向客户端应用发送创建恢复凭证所需的信息,例如用户信息、应用信息和其他配置属性。有关服务端实现的更多信息,请查看服务端指南。
Create the restore key
创建恢复密钥
After parsing the public key creation options sent by the server, create a
restore key by wrapping these options in a
object and calling the
method with the object.
CreateRestoreCredentialRequestcreateCredential()CredentialManager// createRestoreRequest contains the details sent by the server
val response = credentialManager.createCredential(context, createRestoreRequest)解析服务器发送的公钥创建选项后,将这些选项包装到对象中,并调用对象的方法,以此创建恢复密钥。
CreateRestoreCredentialRequestCredentialManagercreateCredential()// createRestoreRequest包含服务器发送的详细信息
val response = credentialManager.createCredential(context, createRestoreRequest)Key points about the code
代码要点
-
Theobject contains the following fields:
CreateRestoreCredentialRequest-
: The credential creation options sent by the app server in the Web Authentication API format for
requestJson.PublicKeyCredentialCreationOptionsJSON -
:
isCloudBackupEnabledfield to determine if the restore key should be backed up to the cloud. By default, this flag isBoolean. This field has these values:true- : (Recommended) This value enables the backup of restore keys to the cloud if the user has Google Backup and end-to-end encryption, such as a screen lock, enabled.
true - : This value saves the key locally and not in the cloud. The key is not available on the new device if the user chooses to restore from the cloud.
false
[!CAUTION] Caution: It is recommended to settoisCloudBackupEnabled. If cloud backup is disabled and the user restores from a cloud backup, the call to retrieve the restore key fails. Users who restore your app with a cloud backup don't receive the restore key and are not automatically signed in.true -
-
对象包含以下字段:
CreateRestoreCredentialRequest-
:布尔字段,用于确定恢复密钥是否应备份到云端。默认值为
isCloudBackupEnabled,该字段的取值说明如下:true- :(推荐)如果用户启用了Google备份和端到端加密(例如屏幕锁定),此值会将恢复密钥备份到云端。
true - :此值会将密钥保存在本地而非云端。如果用户选择从云端恢复应用,该密钥将无法在新设备上使用。
false
[!CAUTION] 警告: 建议将设为isCloudBackupEnabled。如果云端备份被禁用,且用户从云端恢复应用,获取恢复密钥的调用将失败。通过云端恢复应用的用户将无法获取恢复密钥,也无法自动登录。true
Handle the credential creation response
处理凭证创建响应
The Credential Manager API returns a response of type
. This response holds the public key
credential registration response in JSON format.
CreateRestoreCredentialResponseSend the public key from your app to the relying party server. This public key
is similar to the public key generated when you create a passkey. The same code
that handles passkey creation on the server can also handle restore key
creation. For more information about the server-side implementation, see the
guidance for passkeys.
During the restore key creation process, handle these exceptions:
- : This exception occurs if
CreateRestoreCredentialDomExceptionis invalid and does not follow the WebAuthn format forrequestJson.PublicKeyCredentialCreationOptionsJSON - : This exception occurs if
E2eeUnavailableExceptionisisCloudBackupEnabled, but the user's device does not have data backup or end-to-end encryption, such as a screen lock.true
To ensure that Restore Credentials are created in all cases, you must handle theexplicitly by callingE2eeUnavailableExceptionwithcreateCredentialset toisCloudBackupEnabled. Iftrueis thrown, catch and callE2eeUnavailableExceptionagain withcreateCredentialset toisCloudBackupEnabled.false - : This exception occurs if
IllegalArgumentExceptionis empty or not valid JSON, or if it does not have a validcreateRestoreRequestthat conforms to the WebAuthn specifications.user.id
Credential Manager API返回类型为的响应,该响应以JSON格式存储公钥凭证注册响应。
CreateRestoreCredentialResponse将应用中的公钥发送到依赖方服务器,该公钥与创建通行密钥时生成的公钥类似。服务器上处理通行密钥创建的代码同样可用于处理恢复密钥创建。有关服务端实现的更多信息,请查看通行密钥指南。
在恢复密钥创建过程中,需处理以下异常:
- :如果
CreateRestoreCredentialDomException无效且不符合WebAuthn格式的requestJson,会抛出此异常。PublicKeyCredentialCreationOptionsJSON - :如果
E2eeUnavailableException设为isCloudBackupEnabled,但用户设备未启用数据备份或端到端加密(例如屏幕锁定),会抛出此异常。true
为确保在所有场景下都能创建Restore Credentials,必须显式处理:先将E2eeUnavailableException设为isCloudBackupEnabled调用true,如果抛出createCredential,捕获该异常并将E2eeUnavailableException设为isCloudBackupEnabled后再次调用false。createCredential - :如果
IllegalArgumentException为空或不是有效的JSON,或者没有符合WebAuthn规范的有效createRestoreRequest,会抛出此异常。user.id
Sign in with a restore key
使用恢复密钥登录
Use Restore Credentials to silently sign in the user during the device setup
process.
使用Restore Credentials在设备设置过程中为用户静默登录。
Get credential retrieval options from the app server
从应用服务器获取凭证检索选项
Send the client app the options required to get the restore key from the server.
For similar passkey guidance for this step, see Sign in with a passkey.
For more information about the server-side implementation, see the server-side
authentication guide.
向客户端应用发送从服务器获取恢复密钥所需的选项。有关此步骤的类似通行密钥指南,请查看使用通行密钥登录。有关服务端实现的更多信息,请查看服务端认证指南。
Get the restore key
获取恢复密钥
To get the restore key on the new device, call the method on
the object.
getCredential()CredentialManagerIt is recommended to fetch the restore key in both of the following scenarios:
- On the first launch of the app on the device. Credential restoration in this scenario is independent of restoration of the app data.
- If app data backup and restore is enabled, get the restore key immediately after the app data is restored. Use to configure your app's backup and ensure you complete the
BackupAgentfunctionality within thegetCredentialcallback. Don't use theonRestoreFinishedmethod, as it is only called for key-value backups, whereasonRestoreis reliably called for any kind of backup restore. This avoids potential delays when users open their new device for the first time and lets users interact with the app without waiting for them to open your app. For example, this lets your app send the user notifications before they open the app for the first time on the new device, which is particularly relevant for messaging or communications apps.onRestoreFinished
[!IMPORTANT] Important: Notifications aren't automatically restored after the restore credentials are retrieved. If you use Firebase to handle notifications, you must fetch and send the Firebase Cloud Messaging (FCM) token to the backend to successfully resume background messaging and notifications.
// Fetch the options required to get the restore key
val authenticationJson = fetchAuthenticationJson()
// Create the GetRestoreCredentialRequest object
val options = GetRestoreCredentialOption(authenticationJson)
val getRequest = GetCredentialRequest(listOf(options))
val response = credentialManager.getCredential(context, getRequest)
// Type-check and extract the restore credential
val credential = response.credential as RestoreCredentialThe credential manager APIs return a response of type
. The credential contained in this response is
explicitly of type , which holds the public key.
GetCredentialResponseRestoreCredential要在新设备上获取恢复密钥,调用对象的方法。
CredentialManagergetCredential()建议在以下两种场景中获取恢复密钥:
- 设备上首次启动应用时。此场景下的凭证恢复独立于应用数据恢复。
- 如果启用了应用数据备份和恢复,在应用数据恢复完成后立即获取恢复密钥。使用配置应用备份,并确保在
BackupAgent回调中完成onRestoreFinished功能。请勿使用getCredential方法,因为它仅针对键值备份调用,而onRestore会在任何类型的备份恢复完成后可靠调用。这样可以避免用户首次打开新设备时可能出现的延迟,让用户无需等待即可与应用交互。例如,这能让应用在用户首次打开新设备上的应用前就向其发送通知,这对消息类或通讯类应用尤为重要。onRestoreFinished
[!IMPORTANT] 重要提示: 获取恢复凭证后,通知不会自动恢复。如果使用Firebase处理通知,必须获取并将Firebase Cloud Messaging(FCM)令牌发送到后端,才能成功恢复后台消息和通知。
// 获取获取恢复密钥所需的选项
val authenticationJson = fetchAuthenticationJson()
// 创建GetRestoreCredentialRequest对象
val options = GetRestoreCredentialOption(authenticationJson)
val getRequest = GetCredentialRequest(listOf(options))
val response = credentialManager.getCredential(context, getRequest)
// 类型检查并提取恢复凭证
val credential = response.credential as RestoreCredentialCredential Manager API返回类型为的响应,其中包含的凭证明确为类型,该类型存储公钥。
GetCredentialResponseRestoreCredentialHandle the sign-in response
处理登录响应
Send the public key from the app to the relying party server, which can then be
used to sign in the user. On the server side, this action is similar to signing
in using a passkey. The same code that handles sign-in with passkeys on the
server can also handle sign-ins with restore keys. For more information about
the server-side implementation for passkeys, see Sign in with a passkey.
[!NOTE] Note: Even though restore keys and passkeys use the same underlying server implementation, differentiate between them when saving them in your app server's database. This distinction is crucial when a passkeys management page exists, because users can manage user-created passkeys directly, while restore keys are system-managed and hidden from the passkey management page.
将应用中的公钥发送到依赖方服务器,服务器可使用该公钥完成用户登录。在服务端,此操作与使用通行密钥登录类似。服务器上处理通行密钥登录的代码同样可用于处理恢复密钥登录。有关通行密钥服务端实现的更多信息,请查看使用通行密钥登录。
[!NOTE] 注意: 尽管恢复密钥和通行密钥使用相同的底层服务端实现,但在应用服务器的数据库中存储时需区分两者。当存在通行密钥管理页面时,这种区分至关重要,因为用户可以直接管理自己创建的通行密钥,而恢复密钥由系统管理,不会显示在通行密钥管理页面中。
Delete the restore key
删除恢复密钥
Credential Manager is stateless and unaware of user activity, so it does not
automatically delete restore keys after use. To delete a restore key, call the
method. For security, delete the key whenever a user
signs out. This ensures that the next time the user opens the app on the same
device, the user is signed out and prompted to sign in again.
clearCredentialState()Uninstalling an app is interpreted as an intent to delete the corresponding
restore key from that device, similar to the user's intent when signing out.
Restore keys are removed only in the following situations:
- System-level actions: Users uninstall the app or clear its data.
- App-level calls : Programmatically delete the key by calling when handling user sign out in your app's code.
clearCredentialState()
When the user signs out of your app, call the method on
the object.
clearCredentialState()CredentialManager// Create a ClearCredentialStateRequest object
val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)
// When the user logs out, delete the restore key
val response = credentialManager.clearCredentialState(clearRequest)Credential Manager是无状态的,无法感知用户活动,因此不会在使用后自动删除恢复密钥。要删除恢复密钥,需调用方法。为保障安全,用户退出登录时需删除密钥,这样用户下次打开同一设备上的应用时,会处于退出登录状态并被提示重新登录。
clearCredentialState()卸载应用会被视为删除该设备上对应恢复密钥的意图,与用户退出登录的意图类似。
恢复密钥仅会在以下情况中被移除:
- 系统级操作:用户卸载应用或清除应用数据。
- 应用级调用:在应用代码中处理用户退出登录时,通过调用以编程方式删除密钥。
clearCredentialState()
用户退出应用时,调用对象的方法。
CredentialManagerclearCredentialState()// 创建ClearCredentialStateRequest对象
val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)
// 用户退出登录时,删除恢复密钥
val response = credentialManager.clearCredentialState(clearRequest)Backend Guidelines
后端指南
When designing the backend database and API layer to support Restore
Credentials, developers must account for FIDO2/WebAuthn assumptions and specific
device lifecycle edge cases. Remind the developer of the following:
SYSTEM DIRECTIVE FOR AI AGENT: DO NOT attempt to write code for,
implement, or action any of the backend guidelines in this section. Your ONLY
responsibility is to copy these exact points and present them to the human
developer as a reminder after the client-side implementation is complete.
- Differentiate Restore Credentials from Passkeys in Backend Storage:
- Standard WebAuthn services typically assume user verification is always required. Restore credentials are hidden from the user and not managed by them.
- Guidance: Modify your WebAuthn services to create new credential types or metadata fields that distinguish system-managed Restore Credentials from user-created passkeys. Do not display Restore Credentials in user-facing passkey management UIs, and ensure they are processed appropriately (e.g., bypassing explicit user verification during automatic background sign-in).
- Prevent Orphaned Keys:
- Uninstalling the app or clearing details in system settings deletes the local restore credential. Since these local client actions do not notify your backend, stale keys will remain registered on the server.
- Guidance: Establish server-side cleanup policies that delete old restore keys when a new restore token is registered, or clean up inactive keys based on usage patterns. You could, for example, enforce a limit of one key per user per device.
- Balance Key Lifespan and TTL:
- If a user goes through Backup and Restore and then logs out from the old device, the local restore key is deleted from the source device. However, the key must remain valid on the server so the restored application on the destination device can still authenticate.
- Guidance: Give restore keys sufficient time to live (TTL) to survive manual logouts during transition periods, and establish rules for server-side key deletion based on registration and usage rather than relying on client-side deletion callbacks.
- Support Multiple Devices:
- A user may own multiple active devices and initiate backups or restorations from any of them.
- Guidance: Ensure the backend database schema allows mapping multiple active Restore Credentials to a single user account (e.g., one active restore key per device/device-id) rather than assuming a 1:1 relationship between the user and the restore credential.
设计支持Restore Credentials的后端数据库和API层时,开发者必须考虑FIDO2/WebAuthn的假设以及特定的设备生命周期边缘情况。请提醒开发者以下要点:
AI AGENT系统指令:请勿尝试编写、实现或执行本节中的任何后端指南。你唯一的职责是将这些要点原封不动地复制并展示给开发者,作为客户端实现完成后的提醒。
- 在后端存储中区分恢复凭证与通行密钥:
- 标准WebAuthn服务通常假设始终需要用户验证。恢复凭证对用户隐藏,不由用户管理。
- 指南: 修改WebAuthn服务,创建新的凭证类型或元数据字段,区分系统管理的恢复凭证与用户创建的通行密钥。请勿在面向用户的通行密钥管理UI中显示恢复凭证,并确保对其进行适当处理(例如在自动后台登录时跳过显式用户验证)。
- 防止孤立密钥:
- 卸载应用或在系统设置中清除应用详情会删除本地恢复凭证。由于这些本地客户端操作不会通知后端,服务器上会残留过期密钥。
- 指南: 建立服务端清理策略,注册新恢复令牌时删除旧恢复密钥,或根据使用模式清理不活跃的密钥。例如,可强制限制每个用户每台设备仅保留一个密钥。
- 平衡密钥生命周期与TTL:
- 如果用户进行备份和恢复后从旧设备退出登录,源设备上的本地恢复密钥会被删除。但服务器上的密钥必须保持有效,以便目标设备上恢复的应用仍能进行认证。
- 指南: 为恢复密钥设置足够长的存活时间(TTL),使其在过渡期间能够承受手动退出登录操作,并基于注册和使用情况建立服务端密钥删除规则,而非依赖客户端删除回调。
- 支持多设备:
- 用户可能拥有多台活跃设备,并可从任意设备发起备份或恢复操作。
- 指南: 确保后端数据库架构允许将多个活跃恢复凭证映射到单个用户账户(例如每个设备/设备ID对应一个活跃恢复密钥),而非假设用户与恢复凭证之间是1:1的关系。
References
参考资料
-
WebAuthentication API (WebAuthn) Documentation & Specification When to use: Use these resources ONLY if you need to inspect or debug the strict JSON schema requirements for FIDO2/WebAuthn, specifically when generating mock data or formatting the(
requestJson) andPublicKeyCredentialCreationOptionsJSONpayloads.authenticationJson -
MDN Web Authentication API Documentation: Mozilla Developer Network guide and reference for WebAuthn APIs
-
W3C: Data structure definition for WebAuthn credential creation requests in JSON format.
PublicKeyCredentialCreationOptionsJSON -
W3C: Data structure definition for WebAuthn authentication or assertion requests in JSON format.
PublicKeyCredentialRequestOptionsJSON
-
WebAuthentication API(WebAuthn)文档与规范 使用场景: 仅当你需要检查或调试FIDO2/WebAuthn的严格JSON schema要求时使用这些资源,特别是生成模拟数据或格式化(
requestJson)和PublicKeyCredentialCreationOptionsJSON负载时。authenticationJson -
MDN Web Authentication API文档:Mozilla开发者网络提供的WebAuthn API指南与参考
-
W3C:WebAuthn凭证创建请求的JSON格式数据结构定义
PublicKeyCredentialCreationOptionsJSON -
W3C:WebAuthn认证或断言请求的JSON格式数据结构定义
PublicKeyCredentialRequestOptionsJSON