Menerapkan Login dengan Google

Panduan ini menjelaskan cara menerapkan Login dengan Google dan mencakup langkah-langkah berikut:

  • Tambahkan dependensi ke aplikasi Anda.
  • Buat instance CredentialManager.
  • Buat alur panel bawah.
  • Buat alur tombol.
  • Tangani respons login.
  • Menangani error.
  • Menangani logout.

Menambahkan dependensi ke aplikasi

Dalam file build.gradle modul Anda, deklarasikan dependensi menggunakan versi terbaru Credential Manager, Play Services Auth, dan googleid:

Kotlin

dependencies {
    implementation("androidx.credentials:credentials:1.6.0-rc02")
    implementation("androidx.credentials:credentials-play-services-auth:1.6.0-rc02")
    implementation("com.google.android.libraries.identity.googleid:googleid:<latest version>")
}

Groovy

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

Buat instance Credential Manager

Gunakan konteks aplikasi atau aktivitas Anda untuk membuat objek CredentialManager.

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

Membuat alur panel bawah

Sheet bawah adalah UI bawaan Pengelola Kredensial. Penggunaan UI ini menciptakan pengalaman yang konsisten di semua metode autentikasi, seperti sandi, kunci sandi, dan Login dengan Google.

Mengonfigurasi permintaan login untuk akun yang sebelumnya diotorisasi

Coba permintaan login dengan Google menggunakan GetGoogleIdOption untuk mengambil Token ID Google pengguna.

Cuplikan berikut memeriksa apakah akun adalah akun yang diotorisasi.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(true)
    .setNonce(generateSecureRandomNonce())
    .build()

Objek permintaan googleIdOption dikonfigurasi sebagai berikut:

  • Memfilter akun yang sebelumnya diberi otorisasi: Untuk mengambil akun yang diberi otorisasi yang sebelumnya digunakan untuk login ke aplikasi Anda, tetapkan setFilterByAuthorizedAccounts ke true.

    Perhatikan bahwa nilai default untuk setFilterByAuthorizedAccounts adalah true, yang berarti perilaku default untuk UI sheet bawah adalah menampilkan hanya akun yang sebelumnya diberi otorisasi.

  • Tetapkan ID klien server: Tetapkan parameter setServerClientId. webClientId adalah Client ID Web yang Anda siapkan untuk OAuth di Project Google Cloud saat menyelesaikan prasyarat.

  • Aktifkan Login Otomatis (opsional): Untuk mengaktifkan Login Otomatis bagi pengguna yang kembali, gunakan setAutoSelectEnabled(true) dan setFilterByAuthorizedAccounts(true). Untuk pengguna aplikasi Anda, hal ini menghilangkan hambatan yang tidak perlu jika mereka sudah login sebelumnya.

    Login Otomatis hanya memungkinkan jika kriteria berikut terpenuhi:

    • Hanya ada satu akun resmi di perangkat dan akun resmi tersebut sebelumnya digunakan untuk login ke aplikasi di perangkat. Beberapa akun yang diizinkan di perangkat akan menonaktifkan login otomatis.
    • Pengguna belum logout secara eksplisit dari aplikasi selama sesi sebelumnya.
    • Pengguna belum menonaktifkan Login Otomatis di setelan Akun Google mereka.
  • Tetapkan nonce (opsional): Untuk mengaktifkan keamanan yang ditingkatkan, tetapkan nonce untuk verifikasi sisi server. Untuk mencegah serangan replay, Anda dapat menyertakan nonce untuk verifikasi sisi server dengan setNonce(). Pastikan kode sisi server Anda memvalidasi bahwa nonce permintaan dan respons identik.

    Untuk membuat nonce, gunakan fungsi yang mirip dengan fungsi berikut yang membuat nonce acak yang kuat secara kriptografi dengan panjang yang ditentukan dan mengenkodekannya menggunakan Base64:

fun generateSecureRandomNonce(byteLength: Int = 32): String {
    val randomBytes = ByteArray(byteLength)
    SecureRandom().nextBytes(randomBytes)
    return Base64.encodeToString(randomBytes, Base64.NO_WRAP or Base64.URL_SAFE or Base64.NO_PADDING)
}

Meminta login

Periksa apakah pengguna memiliki akun yang diberi otorisasi di perangkat dengan memanggil metode getCredential:

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

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

Mengonfigurasi permintaan login jika tidak ada akun yang diizinkan

Jika tidak ada pengguna yang diberi otorisasi untuk aplikasi Anda di perangkat, CredentialManager akan menampilkan NoCredentialException. Dalam skenario ini, nonaktifkan filter akun yang diizinkan agar pengguna dapat menggunakan akun lain untuk mendaftar.

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

Selanjutnya, minta login dengan cara yang sama seperti yang Anda lakukan untuk akun yang diberi otorisasi.

Buat alur tombol

Gunakan tombol jika Anda ingin pengguna dapat Login dengan Google untuk kondisi berikut:

  • Pengguna menutup UI sheet bawah Pengelola Kredensial.
  • Tidak ada Akun Google di perangkat.
  • Akun yang ada di perangkat memerlukan autentikasi ulang.

Membuat UI tombol

Meskipun hal ini dapat dilakukan dengan tombol Jetpack Compose, Anda dapat menggunakan ikon merek yang telah disetujui sebelumnya dari halaman Panduan Branding Login dengan Google.

Membuat alur login

Buat permintaan login dengan Google menggunakan GetSignInWithGoogleOption untuk mengambil Token ID Google.

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
    serverClientId = WEB_CLIENT_ID
).setNonce(generateSecureRandomNonce())
    .build()

Selanjutnya, minta login dengan cara yang sama seperti yang Anda lakukan untuk UI sheet bawah.

Buat fungsi login bersama untuk sheet bawah dan tombol

Untuk menangani proses login, selesaikan langkah-langkah berikut:

  1. Gunakan fungsi getCredential() CredentialManager. Jika respons berhasil, ekstrak CustomCredential, yang harus berjenis GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.
  2. Konversi objek menjadi GoogleIdTokenCredential menggunakan metode GoogleIdTokenCredential.createFrom().

  3. Validasi kredensial di server pihak tepercaya Anda.

  4. Pastikan Anda menangani error dengan tepat.

fun handleSign(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 the ID for server-side validation.
                    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")
        }
    }
}

Menangani error

Tinjau error yang tercantum di Pemecahan masalah untuk memastikan kode Anda menangani semua kemungkinan skenario error.

Menangani logout

Penting untuk menyediakan mekanisme bagi pengguna Anda untuk logout dari aplikasi Anda. Misalnya, pengguna mungkin memiliki beberapa Akun Google di perangkat dan memutuskan untuk login dari akun yang berbeda. Anda dapat menyediakannya di, misalnya, halaman setelan.

Penyedia kredensial dapat menyimpan sesi kredensial aktif dan menggunakannya untuk membatasi opsi login untuk permintaan login mendatang. Misalnya, kredensial aktif dapat diprioritaskan daripada kredensial lain yang tersedia.

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, sehingga pengguna dapat menggunakan opsi login lengkap pada lain waktu.