Dieser Leitfaden setzt die Implementierung der Authentifizierung mit Passkeys fort. Bevor sich Ihre Nutzer mit Passkeys anmelden können, müssen Sie auch die Anleitung unter Passkeys erstellen ausführen.
Um sich mit einem Passkey zu authentifizieren, müssen Sie zuerst die Optionen abrufen, die zum Abrufen des öffentlichen Schlüssels von Ihrem App-Server erforderlich sind, und dann die Credential Manager API aufrufen, um den öffentlichen Schlüssel abzurufen. Verarbeiten Sie dann die Anmeldeantwort entsprechend.
Übersicht
In diesem Leitfaden werden die Änderungen beschrieben, die in Ihrer Client-App erforderlich sind, um Nutzer mit einem Passkey anzumelden. Außerdem wird die serverseitige Implementierung der App kurz erläutert. Weitere Informationen zur serverseitigen Integration finden Sie unter Serverseitige Passkey-Authentifizierung.
So rufen Sie alle Passkey- und Passwortoptionen ab, die mit dem Konto des Nutzers verknüpft sind:
- Optionen für Anfragen zu Anmeldedaten vom Server abrufen: Senden Sie eine Anfrage von Ihrer App an Ihren Authentifizierungsserver, um den Anmeldevorgang mit Passkey zu starten. Senden Sie vom Server aus die Optionen, die zum Abrufen der Anmeldedaten für den öffentlichen Schlüssel erforderlich sind, sowie eine eindeutige Challenge.
- Objekt erstellen, das zum Abrufen der Anmeldedaten für den öffentlichen Schlüssel erforderlich ist: Umschließen Sie
die vom Server gesendeten Optionen mit einem
GetPublicKeyCredentialOptionObjekt. - (Optional) getCredential vorbereiten: In Android 14 und höher können Sie die Latenz reduzieren, indem Sie die Kontoauswahl mit der Methode
prepareGetCredential()anzeigen, bevor SiegetCredential()aufrufen. - Anmeldevorgang starten: Rufen Sie die Methode
getCredential()auf, um den Nutzer anzumelden. - **Antwort verarbeiten**: Verarbeiten Sie jede der möglichen Antworten zu Anmeldedaten.
- Ausnahmen verarbeiten: Achten Sie darauf, dass Sie Ausnahmen entsprechend verarbeiten.
Optionen für Anfragen zu Anmeldedaten vom Server abrufen
Fordern Sie vom Server die Optionen an, die zum Abrufen der Anmeldedaten für den öffentlichen Schlüssel erforderlich sind, sowie die challenge, die für jeden Anmeldeversuch eindeutig ist. Weitere Informationen zur serverseitigen Implementierung finden Sie unter Challenge
erstellen und Optionen für Anfragen zu Anmeldedaten
erstellen.
Die Optionen sehen in etwa so aus:
{
"challenge": "<your app challenge>",
"allowCredentials": [],
"rpId": "<your app server domain>"
}
Weitere Informationen zu den Feldern finden Sie im Blogpost zur Anmeldung mit einem Passkey.
Objekt erstellen, das zum Abrufen der Anmeldedaten für den öffentlichen Schlüssel erforderlich ist
Erstellen Sie in Ihrer App mit den Optionen ein GetPublicKeyCredentialOption-Objekt.
Im folgenden Beispiel stellt requestJson die vom Server gesendeten Optionen dar.
// Get password logins from the credential provider on the user's device.
val getPasswordOption = GetPasswordOption()
// Get passkeys from the credential provider on the user's device.
val getPublicKeyCredentialOption = GetPublicKeyCredentialOption(
requestJson = requestJson
)
Umschließen Sie dann GetPublicKeyCredentialOption mit einem GetCredentialRequest-Objekt.
val credentialRequest = GetCredentialRequest(
// Include all the sign-in options that your app supports.
listOf(getPasswordOption, getPublicKeyCredentialOption),
// Defines whether you prefer to use only immediately available
// credentials or hybrid credentials.
preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
)
Optional: Latenz bei der Anmeldung reduzieren
In Android 14 oder höher können Sie die Latenz reduzieren, wenn Sie die Konto
auswahl mit der prepareGetCredential() Methode anzeigen, bevor Sie
getCredential() aufrufen.
Die Methode prepareGetCredential() gibt ein
PrepareGetCredentialResponse-Objekt zurück, das im Cache gespeichert wird. So kann die Methode getCredential() im nächsten Schritt die Kontoauswahl mit den im Cache gespeicherten Daten aufrufen.
coroutineScope {
val response = credentialManager.prepareGetCredential(
GetCredentialRequest(
listOf(
// Include all the sign-in options that your app supports
getPublicKeyCredentialOption,
getPasswordOption
)
)
)
}
Anmeldevorgang starten
Rufen Sie die Methode getCredential() auf, um dem Nutzer die Kontoauswahl anzuzeigen. Verwenden Sie das folgende Code-Snippet als Referenz für den Start des Anmeldevorgangs:
// Use an activity-based context to avoid undefined system UI
// launching behavior.
val context = MutableContextWrapper(activityContext)
coroutineScope {
try {
result = credentialManager.getCredential(
// Use MutableContextWrapper to avoid memory leak during configuration changes
context = context,
request = credentialRequest
)
handleSignIn(result)
} catch (e: GetCredentialException) {
// Handle failure
}
}
Antwort verarbeiten
Verarbeiten Sie die Antwort, die eines von verschiedenen Arten von Anmeldedatenobjekten enthalten kann.
fun handleSignIn(result: GetCredentialResponse) {
// Handle the successfully returned credential.
val credential = result.credential
when (credential) {
is PublicKeyCredential -> {
val responseJson = credential.authenticationResponseJson
// Share responseJson i.e. a GetCredentialResponse on your server to
// validate and authenticate
}
is PasswordCredential -> {
val username = credential.id
val password = credential.password
// Use id and password to send to your server to validate
// and authenticate
}
is CustomCredential -> {
// If you are also using any external sign-in libraries, parse them
// here with the utility functions provided.
if (credential.type == ExampleCustomCredential.TYPE) {
try {
val ExampleCustomCredential =
ExampleCustomCredential.createFrom(credential.data)
// Extract the required credentials and complete the authentication as per
// the federated sign in or any external sign in library flow
} catch (e: ExampleCustomCredential.ExampleCustomCredentialParsingException) {
// Unlikely to happen. If it does, you likely need to update the dependency
// version of your external sign-in library.
Log.e(TAG, "Failed to parse an ExampleCustomCredential", e)
}
} else {
// Catch any unrecognized custom credential type here.
Log.e(TAG, "Unexpected type of credential")
}
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential")
}
}
}
Die von der Authentifizierung zurückgegebene PublicKeyCredential ist im Wesentlichen eine signierte Assertion, die so strukturiert ist:
{
"id": "<credential ID>",
"type": "public-key",
"rawId": "<raw credential ID>",
"response": {
"clientDataJSON": "<signed client data containing challenge>",
"authenticatorData": "<authenticator metadata>",
"signature": "<digital signature to be verified>",
"userHandle": "<user ID from credential registration>"
}
}
Auf dem Server müssen Sie die Anmeldedaten überprüfen. Weitere Informationen finden Sie unter Nutzer überprüfen und anmelden.
Ausnahmen verarbeiten
Sie sollten alle Unterklassen-Ausnahmen von GetCredentialException verarbeiten.
Informationen zum Verarbeiten der einzelnen Ausnahmen finden Sie im Leitfaden zur Fehlerbehebung.
coroutineScope {
try {
result = credentialManager.getCredential(
context = activityContext,
request = credentialRequest
)
} catch (e: GetCredentialException) {
Log.e("CredentialManager", "No credential available", e)
}
}