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

Otentikasi Menggunakan Apple di Android

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

Sebelum kamu memulai

Untuk masuk ke 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 .

Konfigurasi Masuk dengan Apple

Di situs Pengembang Apple , lakukan hal berikut:

  1. Kaitkan situs web Anda ke aplikasi Anda seperti yang dijelaskan di bagian pertama dari Mengonfigurasi 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 setelan konsol Firebase .

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

  2. Buat Masuk dengan kunci pribadi Apple . Anda akan memerlukan kunci pribadi dan ID kunci baru Anda di bagian berikutnya.
  3. Jika Anda menggunakan salah satu fitur Firebase Authentication yang mengirim email ke pengguna, termasuk link masuk 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 Firebase console.
  2. Di Firebase console , buka bagian Auth . Pada tab Metode masuk , aktifkan penyedia Apple . Tentukan ID Layanan yang Anda buat di bagian sebelumnya. Selain itu, di bagian konfigurasi alur kode OAuth , tentukan ID Tim Apple Anda serta kunci pribadi dan 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 kebijakan atau persyaratan pengembang yang berlaku dari Apple terkait ID Apple yang dianonimkan ini.

Ini termasuk memperoleh persetujuan pengguna yang diperlukan sebelum Anda mengaitkan informasi pribadi apa pun yang mengidentifikasi secara langsung dengan ID Apple yang dianonimkan. Saat menggunakan Firebase Authentication, tindakan ini dapat mencakup 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 dengan menangani seluruh alur masuk dengan Firebase Android SDK.

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

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

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    

    Kotlin+KTX

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

    Java

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

    Kotlin+KTX

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

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

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

    Java

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

    Kotlin+KTX

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr")
    
  4. Mengautentikasi dengan Firebase menggunakan objek penyedia OAuth. Perhatikan bahwa tidak seperti operasi FirebaseAuth lainnya, ini akan mengontrol UI Anda dengan membuka Tab Chrome Khusus. Akibatnya, jangan merujuk 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 sudah menerima tanggapan. Masuk dengan metode ini menempatkan Aktivitas Anda di latar belakang, yang berarti dapat diklaim kembali oleh sistem selama alur masuk. Untuk memastikan bahwa Anda tidak membuat pengguna mencoba lagi jika ini terjadi, Anda harus memeriksa apakah hasilnya sudah ada.

    Untuk memeriksa apakah ada hasil yang tertunda, panggil getPendingAuthResult() :

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

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

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

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

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

    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 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.

Otentikasi 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:

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.
          }
        });

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.
    })

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

Perhatikan bahwa Apple mengharuskan Anda untuk mendapatkan persetujuan eksplisit dari pengguna sebelum Anda 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:

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.
        }
      }
    });

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.
        }
      });

Lanjutan: Menangani alur masuk secara manual

Anda juga dapat mengautentikasi dengan Firebase menggunakan Akun Apple dengan menangani alur masuk dengan 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—"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:

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

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

    Kemudian, dapatkan hash SHA246 dari nonce sebagai string hex:

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

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

    Anda akan mengirimkan hash SHA256 dari nonce dengan permintaan masuk Anda, yang akan diteruskan oleh Apple tanpa perubahan dalam tanggapannya. 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 lain. Pastikan untuk menyertakan nonce hash sebagai parameter dalam permintaan Anda.

  3. Setelah Anda menerima respons Apple, dapatkan token ID dari respons dan gunakan dan nonce tanpa hash untuk membuat AuthCredential :

    Java

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

    Kotlin+KTX

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

    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.
              // ...
            }
          }
        });
    

    Kotlin+KTX

    auth.signInWithCredential(credential)
          .addOnCompleteListener(this) { 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 kalinya, 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 proyek Firebase Anda, dan dapat digunakan untuk mengidentifikasi pengguna di setiap aplikasi dalam proyek Anda, terlepas dari cara pengguna masuk.

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

  • Di 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 untuk masuk ke aplikasi Anda menggunakan beberapa penyedia autentikasi dengan menautkan kredensial penyedia autentikasi ke akun pengguna yang ada.

Untuk mengeluarkan pengguna, panggil signOut :

Java

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()