Mengautentikasi pengguna dengan Login dengan Google

Login dengan Google membantu Anda mengintegrasikan autentikasi pengguna dengan aplikasi Android dengan cepat. Pengguna dapat menggunakan Akun Google mereka untuk login ke aplikasi Anda, memberikan izin, dan membagikan informasi profil mereka dengan aman ke aplikasi Anda. Library Jetpack Pengelola Kredensial Android membuat integrasi ini lancar, menawarkan pengalaman yang konsisten di seluruh perangkat Android menggunakan satu API.

Dokumen ini memandu Anda menerapkan Login dengan Google di aplikasi Android, cara menyiapkan UI tombol Login dengan Google, dan mengonfigurasi pengalaman pendaftaran dan login sekali ketuk yang dioptimalkan aplikasi. Untuk migrasi perangkat yang lancar, Login dengan Google mendukung login otomatis, dan sifat lintas platformnya di seluruh platform Android, iOS, dan web membantu Anda memberikan akses login untuk aplikasi di perangkat apa pun.

Untuk menyiapkan Login dengan Google, ikuti dua langkah utama berikut:

Mengonfigurasi Login dengan Google sebagai opsi untuk UI sheet bawah Pengelola Kredensial. Hal ini dapat dikonfigurasi untuk otomatis meminta pengguna login. Jika telah menerapkan kunci sandi atau sandi, Anda dapat meminta semua jenis kredensial yang relevan secara bersamaan, sehingga pengguna tidak perlu mengingat opsi yang telah mereka gunakan sebelumnya untuk login.

Sheet bawah Pengelola Kredensial
Gambar 1. UI pemilihan kredensial sheet bawah Pengelola Kredensial

Tambahkan tombol Login dengan Google ke UI aplikasi Anda. Tombol Login dengan Google menawarkan cara yang disederhanakan bagi pengguna untuk menggunakan Akun Google yang sudah ada untuk mendaftar atau login ke aplikasi Android. Pengguna akan mengklik tombol Login dengan Google jika mereka menutup UI sheet bawah, atau jika mereka secara eksplisit ingin menggunakan Akun Google mereka untuk mendaftar dan login. Bagi developer, hal ini berarti orientasi pengguna yang lebih mudah dan pengurangan hambatan selama pendaftaran.

Animasi yang menunjukkan alur Login dengan Google
Gambar 2. UI tombol Login dengan Google Pengelola Kredensial

Dokumen ini menjelaskan cara mengintegrasikan tombol Login dengan Google dan dialog sheet bawah dengan Credential Manager API menggunakan library helper ID Google.

Menyiapkan project konsol API Google

  1. Buka project Anda di API Console, atau buat project jika Anda belum memilikinya.
  2. Di halaman layar izin OAuth, pastikan semua informasi lengkap dan akurat.
    1. Pastikan aplikasi Anda memiliki Nama Aplikasi, Logo Aplikasi, dan Halaman Beranda Aplikasi yang benar. Nilai ini akan ditampilkan kepada pengguna di layar izin Login dengan Google saat mendaftar dan layar Aplikasi & layanan pihak ketiga.
    2. Pastikan Anda telah menentukan URL kebijakan privasi dan persyaratan layanan aplikasi Anda.
  3. Di halaman Kredensial, buat client ID Android untuk aplikasi Anda jika Anda belum memilikinya. Anda harus menentukan nama paket dan tanda tangan SHA-1 aplikasi.
    1. Buka halaman Credentials.
    2. Klik Create credentials > OAuth client ID.
    3. Pilih jenis aplikasi Android.
  4. Di halaman Kredensial, buat client ID "Aplikasi web" baru jika Anda belum melakukannya. Untuk saat ini, Anda dapat mengabaikan kolom "Asal JavaScript yang Diotorisasi" dan "URI pengalihan yang Diotorisasi". Client ID ini akan digunakan untuk mengidentifikasi server backend Anda saat berkomunikasi dengan layanan autentikasi Google.
    1. Buka halaman Credentials.
    2. Klik Create credentials > OAuth client ID.
    3. Pilih jenis Aplikasi web.

Mendeklarasikan dependensi

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

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>"
}

Membuat instance permintaan login dengan Google

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

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

Pertama, periksa apakah pengguna memiliki akun yang sebelumnya telah digunakan untuk login ke aplikasi Anda dengan memanggil API dengan parameter setFilterByAuthorizedAccounts ditetapkan ke true. Pengguna dapat memilih antara akun yang tersedia untuk login.

Jika tidak ada Akun Google resmi yang tersedia, pengguna akan diminta untuk mendaftar dengan akun yang tersedia. Untuk melakukannya, minta pengguna dengan memanggil API lagi dan menetapkan setFilterByAuthorizedAccounts ke false. Pelajari pendaftaran lebih lanjut.

Mengaktifkan login otomatis untuk pengguna yang kembali (direkomendasikan)

Developer harus mengaktifkan login otomatis untuk pengguna yang mendaftar dengan satu akun. Hal ini memberikan pengalaman yang lancar di seluruh perangkat, terutama selama migrasi perangkat, tempat pengguna dapat dengan cepat mendapatkan kembali akses ke akun mereka tanpa memasukkan ulang kredensial. Bagi pengguna Anda, hal ini akan menghilangkan hambatan yang tidak perlu saat mereka sudah login sebelumnya.

Untuk mengaktifkan login otomatis, gunakan setAutoSelectEnabled(true). Login otomatis hanya dapat dilakukan jika kriteria berikut terpenuhi:

  • Ada satu kredensial yang cocok dengan permintaan, yang dapat berupa Akun Google atau sandi, dan kredensial ini cocok dengan akun default di perangkat yang didukung Android.
  • Pengguna belum logout secara eksplisit.
  • Pengguna belum menonaktifkan login otomatis di setelan Akun Google mereka.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Jangan lupa untuk menangani logout dengan benar saat menerapkan login otomatis, sehingga pengguna selalu dapat memilih akun yang tepat setelah mereka logout secara eksplisit dari aplikasi Anda.

Menetapkan nonce untuk meningkatkan keamanan

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

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

Membuat alur Login dengan Google

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

  1. Buat instance GetCredentialRequest, lalu tambahkan googleIdOption yang dibuat sebelumnya menggunakan addCredentialOption() 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 untuk 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.

val request: GetCredentialRequest = Builder()
  .addCredentialOption(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) {

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

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

    // GoogleIdToken credential
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract the ID to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
          // You can use the members of googleIdTokenCredential directly for UX
          // purposes, but don't use them to store or control access to user
          // data. For that you first need to validate the token:
          // pass googleIdTokenCredential.getIdToken() to the backend server.
          GoogleIdTokenVerifier verifier = ... // see validation instructions
          GoogleIdToken idToken = verifier.verify(idTokenString);
          // To get a stable account identifier (e.g. for storing user data),
          // use the subject ID:
          idToken.getPayload().getSubject()
        } 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")
    }
  }
}

Memicu alur tombol Login dengan Google

Untuk memicu alur tombol Login dengan Google, gunakan GetSignInWithGoogleOption, bukan GetGoogleIdOption:

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder()
  .setServerClientId(WEB_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Tangani GoogleIdTokenCredential yang ditampilkan seperti yang dijelaskan dalam contoh kode berikut.

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

  when (credential) {
    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 credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

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

Mengaktifkan pendaftaran untuk pengguna baru (direkomendasikan)

Login dengan Google adalah cara termudah bagi pengguna untuk membuat akun baru dengan aplikasi atau layanan Anda hanya dengan beberapa ketukan.

Jika tidak ada kredensial tersimpan yang ditemukan (tidak ada Akun Google yang ditampilkan oleh getGoogleIdOption), minta pengguna untuk mendaftar. Pertama, periksa apakah setFilterByAuthorizedAccounts(true) untuk melihat apakah ada akun yang sebelumnya digunakan atau tidak. Jika tidak ada yang ditemukan, minta pengguna untuk mendaftar dengan Akun Google-nya menggunakan setFilterByAuthorizedAccounts(false)

Contoh:

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

Setelah Anda membuat instance permintaan pendaftaran Google, luncurkan alur autentikasi. Jika pengguna tidak ingin menggunakan Login dengan Google untuk mendaftar, pertimbangkan untuk mengoptimalkan aplikasi Anda untuk isi otomatis. Setelah pengguna membuat akun, pertimbangkan untuk mendaftarkan mereka ke kunci sandi sebagai langkah terakhir untuk pembuatan akun.

Menangani logout

Saat pengguna logout dari aplikasi Anda, panggil metode clearCredentialState() API untuk menghapus status kredensial pengguna saat ini dari semua penyedia kredensial. Tindakan ini akan memberi tahu semua penyedia kredensial bahwa sesi kredensial yang disimpan untuk aplikasi tertentu harus dihapus.

Penyedia kredensial mungkin telah menyimpan sesi kredensial aktif dan menggunakannya untuk membatasi opsi login untuk panggilan get-credential pada masa mendatang. Misalnya, kredensial aktif dapat diprioritaskan daripada kredensial lain yang tersedia. Saat pengguna logout secara eksplisit dari aplikasi Anda dan untuk mendapatkan opsi login holistik pada lain waktu, Anda harus memanggil API ini agar penyedia menghapus sesi kredensial yang tersimpan.