Aby zezwolić użytkownikom na uwierzytelnianie w Firebase za pomocą ich Apple ID: używając pakietu SDK Firebase do przeprowadzenia pełnego logowania OAuth 2.0.
Zanim zaczniesz
Aby zalogować użytkowników przy użyciu urządzenia Apple, najpierw skonfiguruj funkcję Zaloguj się przez Apple w witrynie Apple dla deweloperów, a potem włącz Apple jako dostawcę logowania projekt Firebase.
Dołącz do programu dla deweloperów Apple
Funkcja Zaloguj się przez Apple może skonfigurować tylko członkowie Apple Developer Program.
Skonfiguruj logowanie się przez Apple
Na urządzeniu Apple w witrynie dla deweloperów:
-
Powiąż witrynę z aplikacją w sposób opisany w pierwszej sekcji z Skonfiguruj funkcję Zaloguj się przez Apple w przeglądarce Gdy pojawi się odpowiedni komunikat, zarejestruj następujący adres URL jako powrotny adres URL:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
Identyfikator projektu Firebase znajdziesz w Konsola Firebase stronie ustawień.
Gdy skończysz, zapisz nowy identyfikator usługi, który będzie Ci potrzebny w przejdź do następnej sekcji.
- Utwórz Zaloguj się za pomocą klucza prywatnego Apple. Potrzebujesz nowego klucza prywatnego i klucza Identyfikator znajdziesz w następnej sekcji.
-
Jeśli używasz dowolnej funkcji Firebase Authentication, która wysyła e-maile do użytkowników, w tym logowanie za pomocą linku e-mail, weryfikacja adresu e-mail, zmiana konta unieważnienie inni, skonfigurować usługę Apple Private Mail relay i zarejestrować
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com
(lub dostosowanej domeny szablonu e-maila), dzięki czemu Apple może przekazywać wysyłane e-maile. od Firebase Authentication na zanonimizowane adresy e-mail Apple.
Włącz Apple jako dostawcę logowania
- Dodaj Firebase do swojego projektu na Androida. Bądź Pamiętaj, aby zarejestrować podpis SHA-1 swojej aplikacji podczas konfigurowania Konsola Firebase.
- W konsoli Firebase otwórz sekcję Uwierzytelnianie. Na karcie Metoda logowania: włącz dostawcę Apple. Podaj identyfikator usługi utworzony w poprzedniej sekcji. Ponadto w Sekcja konfiguracji przepływu kodu OAuth, podaj identyfikator zespołu Apple oraz klucz prywatny i identyfikator klucza utworzone w poprzedniej sekcji.
Zgodność z wymaganiami firmy Apple dotyczącymi zanonimizowanych danych
Zaloguj się przez Apple umożliwia anonimizację danych użytkowników,
łącznie z jego adresem e-mail. Użytkownicy, którzy wybiorą tę opcję
mają adresy e-mail w domenie privaterelay.appleid.com
. Kiedy
korzystasz w aplikacji z funkcji Zaloguj się przez Apple, musisz przestrzegać wszystkich obowiązujących
zasady dla deweloperów lub warunki firmy Apple dotyczące tych zanonimizowanych
Identyfikatory.
Obejmuje to uzyskanie wymaganej zgody użytkownika przed kojarzyć żadnych danych osobowych bezpośrednio umożliwiających identyfikację ze zanonimizowanymi danymi firmy Apple ID. Gdy korzystasz z Uwierzytelniania Firebase, może to obejmować: czynności:
- Połącz adres e-mail z anonimowym identyfikatorem Apple ID lub odwrotnie.
- Łączenie numeru telefonu z anonimowym identyfikatorem Apple ID i odwrotnie
- Połącz nieanonimowe dane społecznościowe (Facebook, Google itp.) z lub na odwrót.
Powyższa lista nie jest wyczerpująca. Zapoznaj się z informacjami o programie dla deweloperów Apple Umowę licencyjną w sekcji Członkostwo na koncie dewelopera, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.
Zarejestruj się za pomocą pakietu SDK Firebase
Na urządzeniach z Androidem najłatwiejszym sposobem uwierzytelniania użytkowników w Firebase jest Konta Apple obsługują cały proces logowania za pomocą Firebase na Androida. SDK.
Aby zalogować się za pomocą pakietu SDK Firebase na Androida, wykonaj te czynności:
Zbuduj instancję instancji
OAuthProvider
za pomocą jego konstruktora identyfikator dostawcyapple.com
:Kotlin+KTX
val provider = OAuthProvider.newBuilder("apple.com")
Java
OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 oprócz domyślnych, które których chcesz żądać od dostawcy uwierzytelniania.
Kotlin+KTX
provider.setScopes(arrayOf("email", "name"))
Java
List<String> scopes = new ArrayList<String>() { { add("email"); add("name"); } }; provider.setScopes(scopes);
Domyślnie, gdy włączona jest opcja jedno konto na adres e-mail, Firebase prosi o zakresy adresów e-mail i nazw. Jeśli zmienisz to ustawienie na Wiele kont na adres e-mail, Firebase nie żąda żadnych zakresów od Apple o ile ich nie określisz.
Opcjonalnie: jeśli chcesz wyświetlać ekran logowania Apple w wybranym języku inny niż angielski, ustaw parametr
locale
. Zobacz Logowanie się przez Dokumenty Apple w obsługiwanych językach.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");
Uwierzytelniaj w Firebase za pomocą obiektu dostawcy OAuth. Pamiętaj, że w przeciwieństwie do innych operacji
FirebaseAuth
, przejmie to kontrolę nad interfejsem użytkownika przez otwórz niestandardową kartę Chrome. Dlatego nie odwołuj się do swojej Aktywności wOnSuccessListener
iOnFailureListener
, które możesz dołączyć, ponieważ odłączy się od razu po uruchomieniu interfejsu użytkownika.Najpierw sprawdź, czy nie wysłaliśmy Ci już odpowiedzi. Logowanie ta metoda umieszcza Twoją aktywność w tle, co oznacza, że może zostać odzyskana przez system podczas logowania. Aby ułatwić aby nie zmuszać użytkownika do ponowienia próby w takim przypadku, sprawdź, czy jest już dostępny wynik.
Aby sprawdzić, czy jest jakiś oczekujący wynik, zadzwoń pod numer
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"); }
Jeśli nie ma żadnych oczekujących wyników, rozpocznij proces logowania, dzwoniąc pod numer
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); } });
W przeciwieństwie do innych dostawców obsługiwanych przez Uwierzytelnienie Firebase Apple nie udostępnia adresu URL zdjęcia.
Ponadto, jeśli użytkownik zdecyduje się nie udostępniać aplikacji e-mail, Apple udostępnia danemu użytkownikowi niepowtarzalny adres e-mail (w formie formularza
xyz@privaterelay.appleid.com
), które udostępnia Twojej aplikacji. Jeśli jeśli skonfigurowano usługę prywatnego przekaźnika poczty e-mail, Apple przekazuje e-maile wysyłane na zanonimizowany adres do rzeczywistego adresu e-mail użytkownika.Apple udostępnia informacje o użytkowniku, takie jak wyświetlana nazwa, aplikacjom przy pierwszym logowaniu się użytkownika. Zwykle Firebase przechowuje wyświetlaną nazwę przy pierwszym logowaniu się w Apple. Dzięki temu
getCurrentUser().getDisplayName()
Jeśli jednak konto Apple było wcześniej używane do logowania użytkownika w aplikacji bez za pomocą Firebase firma Apple nie udostępni Firebase obrazu użytkownika imię i nazwisko.
Ponowne uwierzytelnianie i łączenie kont
Tego samego wzoru można użyć dla atrybutu startActivityForReauthenticateWithProvider()
które mogą służyć do pobierania nowych danych logowania na potrzeby operacji poufnych,
wymagaj ostatniego logowania:
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.
}
});
Za pomocą linkWithCredential()
możesz też łączyć różnych dostawców tożsamości z
istniejących kont.
Pamiętaj, że firma Apple wymaga od użytkowników uzyskania wyraźnej zgody przed połączeniem swoje konta Apple do innych danych.
Aby na przykład połączyć konto na Facebooku z bieżącym kontem Firebase, użyj funkcji token dostępu uzyskany po zalogowaniu użytkownika na Facebooku:
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.
}
}
});
Zaawansowane: logowanie się ręcznie
Możesz też uwierzytelnić się w Firebase za pomocą konta Apple, obsługując za pomocą pakietu Apple Sign-In JS SDK, ręcznie tworząc lub za pomocą biblioteki OAuth, takiej jak AppAuth.
Dla każdego żądania logowania wygeneruj losowy ciąg znaków, „nonce” – służy do sprawdzenia, czy otrzymany token przyznanych w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten jest ważny, aby zapobiec atakom typu „replay”.
Na urządzeniu z Androidem możesz wygenerować szyfrowaną liczbę jednorazową za pomocą
SecureRandom
jak w tym przykładzie: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(); }
Następnie pobierz hasz SHA246 liczby jednorazowej w postaci ciągu szesnastkowego:
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(); }
W żądaniu logowania wysyłasz hasz SHA256 identyfikatora jednorazowego, który Apple przekazuje w odpowiedzi niezmienioną treść. Firebase weryfikuje odpowiedź. przez zaszyfrowanie oryginalnej liczby jednorazowej i porównanie jej z wartością przekazaną przez Apple.
Zainicjuj proces logowania Apple przy użyciu biblioteki OAuth lub innej metody. Bądź , uwzględnij zahaszowaną liczbę jednorazową jako parametr w swoim żądaniu.
Gdy otrzymasz odpowiedź Apple, pobierz token identyfikatora z odpowiedzi i użyj go i niezaszyfrowanej liczby jednorazowej do utworzenia
AuthCredential
:Kotlin+KTX
val credential = OAuthProvider.newCredentialBuilder("apple.com") .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce) .build()
Java
AuthCredential credential = OAuthProvider.newCredentialBuilder("apple.com") .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce) .build();
Uwierzytelnij w Firebase za pomocą danych logowania 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. // ... } } });
Jeśli wywołanie funkcji signInWithCredential
się powiedzie, można użyć funkcji getCurrentUser
metody pobierania danych z konta użytkownika.
Unieważnienie tokena
Apple wymaga, aby aplikacje umożliwiające tworzenie kont mogły inicjować działania użytkowników usunięcia konta w aplikacji, zgodnie z opisem w Informacjach na temat App Store Wytyczne
Ponadto aplikacje obsługujące funkcję Zaloguj się przez Apple powinny używać funkcji Zaloguj się przez Apple. Interfejs API typu REST do unieważniania tokenów użytkowników.
Aby spełnić to wymaganie, wykonaj następujące czynności:
Użyj metody
startActivityForSignInWithProvider()
, aby zalogować się za pomocą urządzenia Apple i uzyskaćAuthResult
.Uzyskaj token dostępu dla dostawcy Apple.
Kotlin+KTX
val oauthCredential: OAuthCredential = authResult.credential val accessToken = oauthCredential.accessToken
Java
OAuthCredential oauthCredential = (OAuthCredential) authResult.getCredential(); String accessToken = oauthCredential.getAccessToken();
Unieważnij token za pomocą interfejsu API
revokeAccessToken
.Kotlin+KTX
mAuth.revokeAccessToken(accessToken) .addOnCompleteListener(this) { task -> if (task.isSuccessful) { // Access token successfully revoked // for the user ... } }
Java
mAuth.revokeAccessToken(accessToken) .addOnCompleteListener(this, new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { // Access token successfully revoked // for the user ... } } });
- Na koniec usuń konto użytkownika (i wszystkie
powiązane dane)
Dalsze kroki
Gdy użytkownik zaloguje się po raz pierwszy, tworzone jest nowe konto użytkownika. powiązane z danymi logowania, czyli z nazwą użytkownika, hasłem i numerem telefonu, numer telefonu lub informacje o dostawcy uwierzytelniania – użytkownik zalogowany. Ten nowy jest przechowywane w ramach projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się loguje.
-
W swoich aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z
FirebaseUser
. Zobacz Zarządzanie użytkownikami. Na liście Firebase Realtime Database i Cloud Storage regułami zabezpieczeń, pobierz ze zmiennej
auth
unikalny identyfikator zalogowanego użytkownika, i używać ich do kontrolowania, do jakich danych użytkownik ma dostęp.
Możesz zezwolić użytkownikom na logowanie się w aplikacji przy użyciu wielokrotnego uwierzytelniania. dostawców, łącząc dane logowania dostawcy uwierzytelniania z istniejącego konta użytkownika.
Aby wylogować użytkownika, wywołaj
signOut
:Kotlin+KTX
Firebase.auth.signOut()
Java
FirebaseAuth.getInstance().signOut();
-