Mengintegrasikan Pengelola Kredensial dengan Login dengan Google

Sheet bawah yang mendukung Pengelola Kredensial menampilkan berbagai identitas untuk dipilih.
Gambar 1. Tampilan dialog sheet bawah Login dengan Google setelah integrasi dengan Credential Manager API.

Dokumen ini menjelaskan cara memigrasikan dialog sheet bawah Login dengan Google dari Google Identity Services (GIS) ke Credential Manager API menggunakan library helper ID Google.

Aplikasi yang menggunakan Credential Manager API dikonfigurasi untuk menampilkan antarmuka pengguna Android yang konsisten kepada pengguna akhir yang memungkinkan mereka memilih dari daftar opsi login yang tersimpan, termasuk akun yang mengaktifkan kunci sandi. Ini adalah Android API yang direkomendasikan untuk menggabungkan berbagai jenis dan penyedia kredensial. Mulai Android 14, pengguna juga dapat memanfaatkan pengelola sandi pihak ketiga dengan Credential Manager API.

Mendeklarasikan dependensi

Dalam file build.gradle modul, deklarasikan dependensi menggunakan versi terbaru:

dependencies {
  // ... other dependencies

  implementation "androidx.credentials:credentials:<latest version>"
  implementation "androidx.credentials:credentials-play-services-auth:<latest version>"
  implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

Ikuti petunjuk untuk menyiapkan project konsol API Google Anda. Ganti panduan tentang penyertaan dependensi dengan petunjuk yang disebutkan di atas.

Membuat instance permintaan login dengan Google

Untuk memulai implementasi Anda, buat instance permintaan login dengan Google. Gunakan GetGoogleIdOption untuk mengambil Token ID Google pengguna.

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .build();

Anda harus memanggil API terlebih dahulu menggunakan parameter setFilterByAuthorizedAccounts yang ditetapkan ke true. Jika tidak ada kredensial yang tersedia, panggil API lagi lalu tetapkan setFilterByAuthorizedAccounts ke false.

Jika Anda ingin membuat pengguna login secara otomatis, jika memungkinkan, aktifkan fitur tersebut dengan setAutoSelectEnabled dalam permintaan GetGoogleIdOption. Login otomatis memungkinkan jika kriteria berikut terpenuhi:

  • Pengguna memiliki tepat satu kredensial yang disimpan untuk aplikasi Anda. Artinya, satu sandi tersimpan atau satu Akun Google tersimpan.
  • Pengguna belum menonaktifkan login otomatis di setelan Akun Google mereka.

Untuk meningkatkan keamanan login dan menghindari serangan replay, gunakan setNonce untuk menyertakan nonce dalam setiap permintaan. Pelajari lebih lanjut cara membuat nonce.

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>);
  .build();

Login dengan Google

Langkah-langkah untuk menyiapkan alur Login dengan Google adalah sebagai berikut:

  1. Buat instance GetCredentialRequest, lalu tambahkan googleIdOption yang dibuat di atas untuk mengambil kredensial.
  2. Teruskan permintaan ini ke panggilan getCredential() (Kotlin) atau getCredentialAsync() (Java) untuk mengambil kredensial pengguna yang tersedia.
  3. Setelah API berhasil, ekstrak CustomCredential yang menyimpan hasil untuk data GoogleIdTokenCredential.
  4. Jenis CustomCredential harus sama dengan nilai GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. Konversi objek menjadi GoogleIdTokenCredential menggunakan metode GoogleIdTokenCredential.createFrom.
  5. Jika konversi berhasil, ekstrak ID GoogleIdTokenCredential, validasi, lalu autentikasi kredensial di server Anda.
  6. Jika konversi gagal dengan GoogleIdTokenParsingException, Anda mungkin perlu mengupdate versi library Login dengan Google.
  7. Tangkap jenis kredensial kustom yang tidak dikenal.

Kotlin

val request: GetCredentialRequest = Builder()
  .addGetCredentialOption(googleIdOption)
  .build()

coroutineScope.launch {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    handleFailure(e)
  }
}

fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {
    is PublicKeyCredential -> {
      // Share responseJson such as a GetCredentialResponse on your server to
      // validate and authenticate
      responseJson = credential.authenticationResponseJson
    }

    is PasswordCredential -> {
      // Send ID and password to your server to validate and authenticate.
      val username = credential.id
      val password = credential.password
    }

    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", 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")
    }
  }
}

Java

GetCredentialRequest request = new GetCredentialRequest.Builder()
  .addGetCredentialOption(googleIdOption)
  .build();

// Launch sign in flow and do getCredential Request to retrieve the credentials
credentialManager.getCredentialAsync(
  requireActivity(),
  request,
  cancellationSignal,
  <executor>,
  new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
    @Override
    public void onResult(GetCredentialResponse result) {
      handleSignIn(result);
    }

    @Override
    public void onError(GetCredentialException e) {
      handleFailure(e);
    }
  }
);

public void handleSignIn(GetCredentialResponse result) {
  // Handle the successfully returned credential.
  Credential credential = result.getCredential();

  if (credential instanceof PublicKeyCredential) {
    String responseJson = ((PublicKeyCredential) credential).getAuthenticationResponseJson();
    // Share responseJson i.e. a GetCredentialResponse on your server to validate and authenticate
  } else if (credential instanceof PasswordCredential) {
    String username = ((PasswordCredential) credential).getId();
    String password = ((PasswordCredential) credential).getPassword();
    // Use id and password to send to your server to validate and authenticate
  } else if (credential instanceof CustomCredential) {
    if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {
      try {
        // Use googleIdTokenCredential and extract id to validate and
        // authenticate on your server
        GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(((CustomCredential) credential).getData());
      } catch (GoogleIdTokenParsingException e) {
        Log.e(TAG, "Received an invalid Google ID token response", 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");
  }
}

Tombol Login dengan Google

Tombol Login dengan Google didukung oleh Pengelola Kredensial dengan library helper ID Google terbaru. Untuk memicu alur tombol Login dengan Google, gunakan GetSignInWithGoogleOption, bukan GetGoogleIdOption, dan tangani GoogleIdTokenCredential yang ditampilkan dengan cara yang sama seperti sebelumnya.

Mendaftar dengan Google

Jika tidak ada hasil yang ditampilkan setelah menyetel setFilterByAuthorizedAccounts ke true saat membuat instance permintaan GetGoogleIdOption dan meneruskan ke GetCredentialsRequest, hal ini menunjukkan bahwa tidak ada akun yang diizinkan untuk login. Pada tahap ini, Anda harus menetapkan setFilterByAuthorizedAccounts(false) dan memanggil Mendaftar dengan Google.

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build();

Setelah Anda membuat instance permintaan pendaftaran Google, luncurkan alur autentikasi dengan cara yang sama seperti yang disebutkan di bagian Login dengan Google.

Menangani logout

Saat pengguna logout dari aplikasi Anda, panggil metode clearCredentialState() API untuk menghapus status kredensial pengguna saat ini dan mereset status internal proses login.