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:
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.
- Buat Masuk dengan kunci pribadi Apple . Anda memerlukan kunci pribadi dan ID kunci baru di bagian berikutnya.
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
- Tambahkan Firebase ke proyek Android Anda . Pastikan untuk mendaftarkan tanda tangan SHA-1 aplikasi Anda saat menyiapkan aplikasi di konsol Firebase.
- 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:
Buat instance
OAuthProvider
menggunakan Builder-nya dengan ID penyediaapple.com
:Kotlin+KTX
val provider = OAuthProvider.newBuilder("apple.com")
Java
OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
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.
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");
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 diOnSuccessListener
danOnFailureListener
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 .
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.
Mulai alur masuk Apple menggunakan pustaka OAuth Anda atau metode lainnya. Pastikan untuk menyertakan nonce hash sebagai parameter dalam permintaan Anda.
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();
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();