Panduan ini melanjutkan penerapan penggunaan kunci sandi untuk autentikasi. Sebelum pengguna dapat login dengan kunci sandi, Anda juga harus menyelesaikan petunjuk di Membuat kunci sandi.
Untuk melakukan autentikasi dengan kunci sandi, Anda harus mengambil opsi yang diperlukan terlebih dahulu untuk mengambil kunci publik dari server aplikasi, lalu memanggil Credential Manager API untuk mengambil kunci publik. Kemudian, tangani respons login dengan tepat.
Ringkasan
Panduan ini berfokus pada perubahan yang diperlukan di aplikasi klien Anda untuk membuat pengguna Anda login dengan kunci sandi, dan memberikan ringkasan singkat tentang penerapan sisi server aplikasi. Untuk mempelajari lebih lanjut integrasi sisi server, lihat Autentikasi kunci sandi sisi server.
Untuk mengambil semua opsi kunci sandi dan sandi yang dikaitkan dengan akun pengguna, selesaikan langkah-langkah berikut:
- Mendapatkan opsi permintaan kredensial dari server: Buat permintaan dari aplikasi Anda ke server autentikasi untuk memulai proses login kunci sandi. Dari server, kirim opsi yang diperlukan untuk mendapatkan kredensial kunci publik, serta tantangan unik.
- Buat objek yang diperlukan untuk mendapatkan kredensial kunci publik: Gabungkan
opsi yang dikirim oleh server dalam objek
GetPublicKeyCredentialOption - (opsional) Siapkan getCredential: Di Android 14 dan yang lebih tinggi, Anda dapat mengurangi latensi dengan menampilkan pemilih akun menggunakan metode
prepareGetCredential()sebelum memanggilgetCredential(). - Luncurkan alur login: Panggil metode
getCredential()untuk login pengguna - Menangani respons: Menangani setiap kemungkinan respons kredensial.
- Menangani pengecualian: Pastikan Anda menangani pengecualian dengan tepat.
1. Mendapatkan opsi permintaan kredensial dari server
Minta server untuk mendapatkan opsi yang diperlukan untuk mendapatkan kredensial kunci publik,
serta challenge, yang unik untuk setiap upaya login. Untuk mempelajari lebih lanjut penerapan sisi server, lihat Membuat tantangan dan Membuat opsi permintaan kredensial.
Opsinya akan terlihat seperti berikut:
{
"challenge": "<your app challenge>",
"allowCredentials": [],
"rpId": "<your app server domain>"
}
Untuk mempelajari kolom lebih lanjut, lihat postingan blog tentang login dengan kunci sandi.
2. Buat objek yang diperlukan untuk mendapatkan kredensial kunci publik
Di aplikasi Anda, gunakan opsi untuk membuat objek GetPublicKeyCredentialOption.
Dalam contoh berikut, requestJson mewakili opsi yang dikirim oleh server.
// 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
)
Kemudian, bungkus GetPublicKeyCredentialOption dalam objek GetCredentialRequest.
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
)
3. Opsional: Mengurangi latensi login
Di Android 14 atau yang lebih baru, Anda dapat mengurangi latensi saat menampilkan pemilih
akun dengan menggunakan metode prepareGetCredential() sebelum memanggil
getCredential().
Metode prepareGetCredential() menampilkan objek
PrepareGetCredentialResponse yang di-cache. Hal ini memungkinkan metode
getCredential() di langkah berikutnya memunculkan pemilih akun
dengan data yang di-cache.
coroutineScope {
val response = credentialManager.prepareGetCredential(
GetCredentialRequest(
listOf(
// Include all the sign-in options that your app supports
getPublicKeyCredentialOption,
getPasswordOption
)
)
)
}
4. Luncurkan alur login
Panggil metode getCredential() untuk menampilkan pemilih akun kepada pengguna. Gunakan cuplikan kode berikut sebagai referensi cara meluncurkan alur login:
coroutineScope {
try {
result = credentialManager.getCredential(
// Use an activity-based context to avoid undefined system UI
// launching behavior.
context = activityContext,
request = credentialRequest
)
handleSignIn(result)
} catch (e: GetCredentialException) {
// Handle failure
}
}
5. Menangani respons
Tangani respons, yang dapat berisi salah satu dari berbagai jenis objek kredensial.
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")
}
}
}
PublicKeyCredential yang ditampilkan dari autentikasi pada dasarnya adalah pernyataan
bertanda tangan, yang disusun sebagai berikut:
{
"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>"
}
}
Di server, Anda harus memverifikasi kredensial. Untuk mempelajari lebih lanjut, lihat Memverifikasi dan login pengguna.
6. Menangani pengecualian
Anda harus menangani semua pengecualian subkelas GetCredentialException.
Untuk mempelajari cara menangani setiap pengecualian, lihat panduan pemecahan masalah.
coroutineScope {
try {
result = credentialManager.getCredential(
context = activityContext,
request = credentialRequest
)
} catch (e: GetCredentialException) {
Log.e("CredentialManager", "No credential available", e)
}
}