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

Otentikasi Menggunakan Apple di Android

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

Anda dapat mengizinkan pengguna mengautentikasi dengan Firebase menggunakan ID Apple mereka dengan menggunakan Firebase SDK untuk menjalankan alur masuk OAuth 2.0 menyeluruh.

Sebelum kamu memulai

Untuk memasukkan pengguna menggunakan Apple, pertama-tama konfigurasikan Masuk dengan Apple di situs pengembang Apple, lalu aktifkan Apple sebagai penyedia masuk untuk proyek Firebase Anda.

Bergabunglah dengan Program Pengembang Apple

Masuk dengan Apple hanya dapat dikonfigurasi oleh anggota Program Pengembang Apple .

Konfigurasikan Masuk dengan Apple

Di situs Pengembang Apple , lakukan hal berikut:

  1. Kaitkan situs web Anda ke aplikasi seperti yang dijelaskan di bagian pertama Konfigurasi Masuk dengan Apple untuk web . Saat diminta, daftarkan URL berikut sebagai URL Pengembalian:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Anda bisa mendapatkan ID proyek Firebase di halaman pengaturan Firebase console .

    Setelah selesai, catat ID Layanan baru Anda, yang akan Anda perlukan di bagian berikutnya.

  2. Buat Masuk dengan kunci pribadi Apple . Anda memerlukan kunci pribadi dan ID kunci baru di bagian berikutnya.
  3. Jika Anda menggunakan salah satu fitur Firebase Authentication yang mengirim email ke pengguna, termasuk masuk tautan email, verifikasi alamat email, pencabutan perubahan akun, dan lainnya, konfigurasikan layanan relai email pribadi Apple dan daftarkan noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (atau domain template email khusus Anda) sehingga Apple dapat menyampaikan email yang dikirim oleh Firebase Authentication ke alamat email Apple yang dianonimkan.

Aktifkan Apple sebagai penyedia masuk

  1. Tambahkan Firebase ke proyek Android Anda . Pastikan untuk mendaftarkan tanda tangan SHA-1 aplikasi Anda saat menyiapkan aplikasi di konsol Firebase.
  2. Di konsol Firebase , buka bagian Auth . Pada tab Metode masuk , aktifkan penyedia Apple . Tentukan ID Layanan yang Anda buat di bagian sebelumnya. Selain itu, di bagian konfigurasi aliran kode OAuth , tentukan ID Tim Apple Anda dan kunci pribadi serta ID kunci yang Anda buat di bagian sebelumnya.

Patuhi persyaratan data anonim Apple

Masuk dengan Apple memberi pengguna opsi untuk menganonimkan data mereka, termasuk alamat email mereka, saat masuk. Pengguna yang memilih opsi ini memiliki alamat email dengan domain privaterelay.appleid.com . Saat Anda menggunakan Masuk dengan Apple di aplikasi Anda, Anda harus mematuhi semua kebijakan atau persyaratan pengembang yang berlaku dari Apple terkait ID Apple yang dianonimkan ini.

Ini termasuk mendapatkan persetujuan pengguna yang diperlukan sebelum Anda mengaitkan informasi pribadi yang mengidentifikasi secara langsung dengan ID Apple yang dianonimkan. Saat menggunakan Firebase Authentication, ini mungkin termasuk tindakan berikut:

  • Tautkan alamat email ke ID Apple yang dianonimkan atau sebaliknya.
  • Tautkan nomor telepon ke ID Apple yang dianonimkan atau sebaliknya
  • Tautkan kredensial sosial non-anonim (Facebook, Google, dll) ke ID Apple yang dianonimkan atau sebaliknya.

Daftar di atas tidak lengkap. Lihat Perjanjian Lisensi Program Pengembang Apple di bagian Keanggotaan akun pengembang Anda untuk memastikan aplikasi Anda memenuhi persyaratan Apple.

Tangani alur masuk dengan Firebase SDK

Di Android, cara termudah untuk mengautentikasi pengguna Anda dengan Firebase menggunakan akun Apple mereka 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 apple.com :

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    
  2. Opsional: Tentukan cakupan OAuth 2.0 tambahan di luar default yang ingin Anda minta dari penyedia autentikasi.

    Kotlin+KTX

    provider.setScopes(arrayOf("email", "name"))
    

    Java

    List<String> scopes =
        new ArrayList<String>() {
          {
            add("email");
            add("name");
          }
        };
    provider.setScopes(scopes);
    

    Secara default, saat Satu akun per alamat email diaktifkan, Firebase meminta cakupan email dan nama. Jika Anda mengubah setelan ini ke Beberapa akun per alamat email , Firebase tidak akan meminta cakupan apa pun dari Apple kecuali Anda menentukannya.

  3. Opsional: Jika Anda ingin menampilkan layar masuk Apple dalam bahasa selain bahasa Inggris, setel parameter locale . Lihat dokumen Masuk dengan Apple untuk lokal yang didukung.

    Kotlin+KTX

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr")
    

    Java

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    
  4. Autentikasi dengan Firebase menggunakan objek penyedia OAuth. Perhatikan bahwa tidak seperti operasi FirebaseAuth lainnya, ini akan mengontrol UI Anda dengan membuka Tab Chrome Khusus. Oleh karena itu, 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 pending = auth.pendingAuthResult
    if (pending != null) {
        pending.addOnSuccessListener { authResult ->
            Log.d(TAG, "checkPending:onSuccess:$authResult")
            // Get the user profile with authResult.getUser() and
            // authResult.getAdditionalUserInfo(), and the ID
            // token from Apple with authResult.getCredential().
        }.addOnFailureListener { e ->
            Log.w(TAG, "checkPending:onFailure", e)
        }
    } else {
        Log.d(TAG, "pending: null")
    }
    

    Java

    mAuth = FirebaseAuth.getInstance();
    Task<AuthResult> pending = mAuth.getPendingAuthResult();
    if (pending != null) {
        pending.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                Log.d(TAG, "checkPending:onSuccess:" + authResult);
                // Get the user profile with authResult.getUser() and
                // authResult.getAdditionalUserInfo(), and the ID
                // token from Apple with authResult.getCredential().
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "checkPending:onFailure", e);
            }
        });
    } else {
        Log.d(TAG, "pending: null");
    }
    

    Jika tidak ada hasil yang tertunda, mulai alur masuk, dengan memanggil startActivityForSignInWithProvider() :

    Kotlin+KTX

    auth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener { authResult ->
                // Sign-in successful!
                Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}")
                val user = authResult.user
                // ...
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "activitySignIn:onFailure", e)
            }
    

    Java

    mAuth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Sign-in successful!
                            Log.d(TAG, "activitySignIn:onSuccess:" + authResult.getUser());
                            FirebaseUser user = authResult.getUser();
                            // ...
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.w(TAG, "activitySignIn:onFailure", e);
                        }
                    });
    

    Tidak seperti penyedia lain yang didukung oleh Firebase Auth, Apple tidak menyediakan URL foto.

    Selain itu, saat pengguna memilih untuk tidak membagikan email mereka dengan aplikasi, Apple menyediakan alamat email unik untuk pengguna tersebut (dalam bentuk xyz@privaterelay.appleid.com ), yang dibagikan dengan aplikasi Anda. Jika Anda mengonfigurasi layanan relai email pribadi, Apple akan meneruskan email yang dikirim ke alamat anonim ke alamat email asli pengguna.

    Apple hanya membagikan informasi pengguna seperti nama tampilan dengan aplikasi saat pertama kali pengguna masuk. Biasanya, Firebase menyimpan nama tampilan saat pertama kali pengguna masuk dengan Apple, yang bisa Anda dapatkan dengan getCurrentUser().getDisplayName() . Namun, jika sebelumnya Anda menggunakan Apple untuk memasukkan pengguna ke aplikasi tanpa menggunakan Firebase, Apple tidak akan memberikan nama tampilan pengguna kepada Firebase.

Autentikasi ulang dan penautan akun

Pola yang sama dapat digunakan dengan startActivityForReauthenticateWithProvider() yang dapat Anda gunakan untuk mengambil kredensial baru untuk operasi sensitif yang memerlukan proses masuk baru-baru ini:

Kotlin+KTX

// The user is already signed-in.
val firebaseUser = auth.getCurrentUser()

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener( 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( e -> {
        // Handle failure.
    })

Java

// The user is already signed-in.
FirebaseUser firebaseUser = mAuth.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.
          }
        });

Dan, Anda dapat menggunakan linkWithCredential() untuk menautkan berbagai penyedia identitas ke akun yang ada.

Perhatikan bahwa Apple mengharuskan Anda mendapatkan persetujuan eksplisit dari pengguna sebelum menautkan akun Apple mereka ke data lain.

Misalnya, untuk menautkan akun Facebook ke akun Firebase saat ini, gunakan token akses yang Anda dapatkan dari memasukkan pengguna ke Facebook:

Kotlin+KTX

// Initialize a Facebook credential with a Facebook access token.
val credential = FacebookAuthProvider.getCredential(token.getToken())

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, task -> {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      });

Java

// Initialize a Facebook credential with a Facebook access token.
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      }
    });

Lanjutan: Tangani alur masuk secara manual

Anda juga dapat mengautentikasi dengan Firebase menggunakan Akun Apple dengan menangani alur masuk menggunakan Apple Sign-In JS SDK, membuat alur OAuth secara manual, atau dengan menggunakan pustaka OAuth seperti AppAuth .

  1. Untuk setiap permintaan masuk, buat string acak—sebuah "nonce"—yang akan Anda gunakan untuk memastikan token ID yang Anda dapatkan diberikan secara khusus sebagai tanggapan atas permintaan autentikasi aplikasi Anda. Langkah ini penting untuk mencegah serangan replay.

    Anda dapat membuat nonce yang aman secara kriptografis di Android dengan SecureRandom , seperti dalam contoh berikut:

    Kotlin+KTX

    private fun generateNonce(length: Int): String {
        val generator = SecureRandom()
    
        val charsetDecoder = StandardCharsets.US_ASCII.newDecoder()
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE)
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE)
    
        val bytes = ByteArray(length)
        val inBuffer = ByteBuffer.wrap(bytes)
        val outBuffer = CharBuffer.allocate(length)
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes)
            inBuffer.rewind()
            charsetDecoder.reset()
            charsetDecoder.decode(inBuffer, outBuffer, false)
        }
        outBuffer.flip()
        return outBuffer.toString()
    }
    

    Java

    private String generateNonce(int length) {
        SecureRandom generator = new SecureRandom();
    
        CharsetDecoder charsetDecoder = StandardCharsets.US_ASCII.newDecoder();
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE);
    
        byte[] bytes = new byte[length];
        ByteBuffer inBuffer = ByteBuffer.wrap(bytes);
        CharBuffer outBuffer = CharBuffer.allocate(length);
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes);
            inBuffer.rewind();
            charsetDecoder.reset();
            charsetDecoder.decode(inBuffer, outBuffer, false);
        }
        outBuffer.flip();
        return outBuffer.toString();
    }
    

    Kemudian, dapatkan hash SHA246 dari nonce sebagai string hex:

    Kotlin+KTX

    private fun sha256(s: String): String {
        val md = MessageDigest.getInstance("SHA-256")
        val digest = md.digest(s.toByteArray())
        val hash = StringBuilder()
        for (c in digest) {
            hash.append(String.format("%02x", c))
        }
        return hash.toString()
    }
    

    Java

    private String sha256(String s) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(s.getBytes());
        StringBuilder hash = new StringBuilder();
        for (byte c: digest) {
            hash.append(String.format("%02x", c));
        }
        return hash.toString();
    }
    

    Anda akan mengirimkan hash SHA256 dari nonce dengan permintaan masuk Anda, yang akan diteruskan oleh Apple tanpa perubahan sebagai tanggapan. Firebase memvalidasi respons dengan hashing nonce asli dan membandingkannya dengan nilai yang diteruskan oleh Apple.

  2. Mulai alur masuk Apple menggunakan pustaka OAuth Anda atau metode lainnya. Pastikan untuk menyertakan nonce hash sebagai parameter dalam permintaan Anda.

  3. Setelah Anda menerima respons Apple, dapatkan token ID dari respons dan gunakan itu serta nonce yang tidak di-hash untuk membuat AuthCredential :

    Kotlin+KTX

    val credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build()
    

    Java

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    
  4. Autentikasi dengan Firebase menggunakan kredensial Firebase:

    Kotlin+KTX

    auth.signInWithCredential(credential)
          .addOnCompleteListener(this) { task ->
              if (task.isSuccessful) {
                // User successfully signed in with Apple ID token.
                // ...
              }
          }
    

    Java

    mAuth.signInWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
          @Override
          public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
              // User successfully signed in with Apple ID token.
              // ...
            }
          }
        });
    

Jika panggilan ke signInWithCredential berhasil, Anda dapat menggunakan metode getCurrentUser untuk mendapatkan data akun pengguna.

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();