Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Otentikasi Menggunakan OpenID Connect di Android

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Jika Anda mengupgrade ke Firebase Authentication dengan Identity Platform, Anda dapat mengautentikasi pengguna Anda dengan Firebase menggunakan penyedia yang sesuai dengan OpenID Connect (OIDC) pilihan Anda. Ini memungkinkan untuk menggunakan penyedia identitas yang tidak didukung secara native oleh Firebase.

Sebelum kamu memulai

Untuk memasukkan pengguna menggunakan penyedia OIDC, Anda harus terlebih dahulu mengumpulkan beberapa informasi dari penyedia:

  • Client ID : String unik untuk penyedia yang mengidentifikasi aplikasi Anda. Penyedia Anda mungkin memberi Anda ID klien yang berbeda untuk setiap platform yang Anda dukung. Ini adalah salah satu nilai klaim aud dalam token ID yang dikeluarkan oleh penyedia Anda.

  • Rahasia klien : String rahasia yang digunakan penyedia untuk mengonfirmasi kepemilikan ID klien. Untuk setiap ID klien, Anda memerlukan rahasia klien yang cocok. (Nilai ini diperlukan hanya jika Anda menggunakan alur kode autentikasi , yang sangat disarankan.)

  • Penerbit : String yang mengidentifikasi penyedia Anda. Nilai ini harus berupa URL yang, jika ditambahkan dengan /.well-known/openid-configuration , merupakan lokasi dokumen penemuan OIDC penyedia. Misalnya, jika penerbitnya adalah https://auth.example.com , dokumen penemuan harus tersedia di https://auth.example.com/.well-known/openid-configuration .

Setelah Anda memiliki informasi di atas, aktifkan OpenID Connect sebagai penyedia login untuk project Firebase Anda:

  1. Tambahkan Firebase ke proyek Android Anda .

  2. Jika Anda belum mengupgrade ke Firebase Authentication dengan Identity Platform, lakukanlah. Otentikasi OpenID Connect hanya tersedia di proyek yang ditingkatkan.

  3. Di laman Penyedia masuk di Firebase console, klik Tambahkan penyedia baru , lalu klik OpenID Connect .

  4. Pilih apakah Anda akan menggunakan aliran kode otorisasi atau aliran hibah implisit .

    Anda harus selalu menggunakan aliran kode jika penyedia Anda mendukungnya . Alur implisit kurang aman dan sangat tidak disarankan untuk menggunakannya.

  5. Beri nama untuk penyedia ini. Catat ID penyedia yang dihasilkan: sesuatu seperti oidc.example-provider . Anda memerlukan ID ini saat menambahkan kode masuk ke aplikasi.

  6. Tentukan ID klien dan rahasia klien Anda, serta string penerbit penyedia Anda. Nilai ini harus sama persis dengan nilai yang diberikan penyedia Anda kepada Anda.

  7. Simpan perubahan Anda.

Tangani alur masuk dengan Firebase SDK

Jika Anda membuat aplikasi Android, cara termudah untuk mengautentikasi pengguna Anda dengan Firebase menggunakan penyedia OIDC Anda adalah menangani seluruh alur masuk dengan Firebase Android SDK.

Untuk menangani alur masuk dengan Firebase Android SDK, ikuti langkah berikut:

  1. Buat instance OAuthProvider menggunakan Builder -nya dengan ID penyedia

    Kotlin+KTX

    val providerBuilder = OAuthProvider.newBuilder("oidc.example-provider")

    Java

    OAuthProvider.Builder providerBuilder = OAuthProvider.newBuilder("oidc.example-provider");

  2. Opsional : Tentukan parameter OAuth khusus tambahan yang ingin Anda kirim dengan permintaan OAuth.

    Kotlin+KTX

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com")

    Java

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com");

    Hubungi penyedia OIDC Anda untuk mengetahui parameter yang mereka dukung. Perhatikan bahwa Anda tidak dapat meneruskan parameter yang diperlukan Firebase dengan setCustomParameters() . Parameter ini adalah client_id , response_type , redirect_uri , state , scope dan response_mode .

  3. Opsional : Tentukan cakupan OAuth 2.0 tambahan di luar profil dasar yang ingin Anda minta dari penyedia autentikasi.

    Kotlin+KTX

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    providerBuilder.scopes = listOf("mail.read", "calendars.read")

    Java

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    List<String> scopes =
            new ArrayList<String>() {
                {
                    add("mail.read");
                    add("calendars.read");
                }
            };
    providerBuilder.setScopes(scopes);

    Hubungi penyedia OIDC Anda untuk cakupan yang mereka gunakan.

  4. Autentikasi dengan Firebase menggunakan objek penyedia OAuth. Perhatikan bahwa tidak seperti operasi FirebaseAuth lainnya, ini akan mengontrol UI Anda dengan memunculkan Tab Chrome Khusus . Akibatnya, jangan mereferensikan Aktivitas Anda di OnSuccessListener dan OnFailureListener yang Anda lampirkan karena keduanya akan segera terlepas saat operasi memulai UI.

    Anda harus terlebih dahulu memeriksa apakah Anda telah menerima tanggapan. Masuk dengan metode ini menempatkan Aktivitas Anda di latar belakang, yang berarti dapat diklaim ulang oleh sistem selama alur masuk. Untuk memastikan bahwa Anda tidak membuat pengguna mencoba lagi jika hal ini terjadi, Anda harus memeriksa apakah hasilnya sudah ada.

    Untuk memeriksa apakah ada hasil yang tertunda, panggil getPendingAuthResult :

    Kotlin+KTX

    val pendingResultTask = firebaseAuth.pendingAuthResult
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
            .addOnSuccessListener {
                // User is signed in.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                // The OAuth secret can be retrieved by calling:
                // ((OAuthCredential)authResult.getCredential()).getSecret().
            }
            .addOnFailureListener {
                // Handle failure.
            }
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Java

    Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
                .addOnSuccessListener(
                        new OnSuccessListener<AuthResult>() {
                            @Override
                            public void onSuccess(AuthResult authResult) {
                                // User is signed in.
                                // IdP data available in
                                // authResult.getAdditionalUserInfo().getProfile().
                                // The OAuth access token can also be retrieved:
                                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                                // The OAuth secret can be retrieved by calling:
                                // ((OAuthCredential)authResult.getCredential()).getSecret().
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                // Handle failure.
                            }
                        });
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Untuk memulai alur masuk, panggil startActivityForSignInWithProvider :

    Kotlin+KTX

    firebaseAuth
        .startActivityForSignInWithProvider( /* activity = */this, provider.build())
        .addOnSuccessListener {
            // User is signed in.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // ((OAuthCredential)authResult.getCredential()).getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    firebaseAuth
            .startActivityForSignInWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is signed in.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // ((OAuthCredential)authResult.getCredential()).getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  5. Sementara contoh di atas berfokus pada alur masuk, Anda juga memiliki kemampuan untuk menautkan penyedia OIDC ke pengguna yang sudah ada menggunakan startActivityForLinkWithProvider . Misalnya, Anda dapat menautkan beberapa penyedia ke pengguna yang sama sehingga memungkinkan mereka masuk dengan keduanya.

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForLinkWithProvider( /* activity = */this, provider.build())
        .addOnSuccessListener {
            // Provider credential is linked to the current user.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // authResult.getCredential().getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // authResult.getCredential().getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForLinkWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Provider credential is linked to the current user.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // authResult.getCredential().getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // authResult.getCredential().getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  6. Pola yang sama dapat digunakan dengan startActivityForReauthenticateWithProvider yang dapat digunakan untuk mengambil kredensial baru untuk operasi sensitif yang memerlukan login baru-baru ini.

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForReauthenticateWithProvider( /* activity = */this, provider.build())
        .addOnSuccessListener {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is re-authenticated with fresh tokens and
                            // should be able to perform sensitive operations
                            // like account deletion and email or password
                            // update.
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

Tangani alur masuk secara manual

Jika Anda telah mengimplementasikan alur masuk OpenID Connect di aplikasi, Anda dapat menggunakan token ID secara langsung untuk mengautentikasi dengan Firebase:

Kotlin+KTX

val providerId = "oidc.example-provider" // As registered in Firebase console.
val credential = oAuthCredential(providerId) {
    setIdToken(idToken) // ID token from OpenID Connect flow.
}
Firebase.auth
    .signInWithCredential(credential)
    .addOnSuccessListener { authResult ->
        // User is signed in.

        // IdP data available in:
        //    authResult.additionalUserInfo.profile
    }
    .addOnFailureListener { e ->
        // Handle failure.
    }

Java

AuthCredential credential = OAuthProvider
        .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
        .setIdToken(idToken)  // ID token from OpenID Connect flow.
        .build();
FirebaseAuth.getInstance()
        .signInWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // User is signed in.

                // IdP data available in:
                //    authResult.getAdditionalUserInfo().getProfile()
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Handle failure.
            }
        });

Langkah selanjutnya

Setelah pengguna masuk untuk pertama kali, akun pengguna baru dibuat dan ditautkan ke kredensial—yaitu, nama pengguna dan sandi, nomor telepon, atau informasi penyedia autentikasi—yang digunakan pengguna untuk masuk. Akun baru ini disimpan sebagai bagian dari project Firebase Anda, dan dapat digunakan untuk mengidentifikasi pengguna di setiap aplikasi dalam project Anda, terlepas dari cara pengguna login.

  • Di aplikasi Anda, Anda bisa mendapatkan informasi profil dasar pengguna dari objek FirebaseUser . Lihat Kelola Pengguna .

  • Dalam Aturan Keamanan Firebase Realtime Database dan Cloud Storage, Anda bisa mendapatkan ID pengguna unik pengguna yang masuk dari variabel auth , dan menggunakannya untuk mengontrol data apa yang dapat diakses pengguna.

Anda dapat mengizinkan pengguna masuk ke aplikasi Anda menggunakan beberapa penyedia autentikasi dengan menautkan kredensial penyedia autentikasi ke akun pengguna yang ada.

Untuk mengeluarkan pengguna, panggil signOut :

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();