Aby zezwolić użytkownikom na uwierzytelnianie w Firebase za pomocą ich Apple ID: używając pakietu SDK Firebase do przeprowadzenia pełnego procesu 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ć się
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.
- 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 Umowy licencyjnej w sekcji Członkostwo na koncie dewelopera, aby aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.
Zarejestruj się za pomocą pakietu SDK Firebase
Jeśli tworzysz aplikację internetową, najprostszy sposób uwierzytelniania użytkowników Cały proces logowania odbywa się za pomocą usługi Firebase, która używa kont Apple, pakiet SDK Firebase JavaScript.
Aby zalogować się za pomocą pakietu SDK Firebase JavaScript, postępuj zgodnie z tymi wskazówkami kroki:
Utwórz instancję OAuthProvider, używając odpowiedniej wartości identyfikator dostawcy apple.com.
Web
import { OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('apple.com');
Web
var provider = new firebase.auth.OAuthProvider('apple.com');
Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 oprócz domyślnych, które których chcesz żądać od dostawcy uwierzytelniania.
Web
provider.addScope('email'); provider.addScope('name');
Web
provider.addScope('email'); provider.addScope('name');
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.Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Uwierzytelniaj w Firebase za pomocą obiektu dostawcy OAuth. Dostępne opcje poproś użytkowników o zalogowanie się na konta Apple przez otwarcie pojawi się wyskakujące okienko lub przekierujemy Cię na stronę logowania. Metoda przekierowania to na urządzeniach mobilnych.
Aby zalogować się za pomocą wyskakującego okienka, zadzwoń pod numer
signInWithPopup()
:Web
import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // The signed-in user info. const user = result.user; // Apple credential const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; // IdP data available using getAdditionalUserInfo(result) // ... }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Web
firebase .auth() .signInWithPopup(provider) .then((result) => { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // The signed-in user info. var user = result.user; // You can also get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // IdP data available using getAdditionalUserInfo(result) // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
Aby zalogować się, przekierowując na stronę logowania, wybierz
signInWithRedirect()
:
Web
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
Web
firebase.auth().signInWithRedirect(provider);
Gdy użytkownik zaloguje się i wróci na stronę, wyświetli się strona wynik logowania, dzwoniąc pod numer
getRedirectResult()
:Web
import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth"; // Result from Redirect auth flow. const auth = getAuth(); getRedirectResult(auth) .then((result) => { const credential = OAuthProvider.credentialFromResult(result); if (credential) { // You can also get the Apple OAuth Access and ID Tokens. const accessToken = credential.accessToken; const idToken = credential.idToken; } // The signed-in user info. const user = result.user; }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Web
// Result from Redirect auth flow. firebase .auth() .getRedirectResult() .then((result) => { if (result.credential) { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // You can get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // IdP data available in result.additionalUserInfo.profile. // ... } // The signed-in user info. var user = result.user; }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
Możesz w nim też wykrywać i poprawiać błędy. Lista błędów zapoznaj się z Dokumentacja API
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 skonfigurujesz usługę prywatnej usługi przekaźnika poczty e-mail, Apple przekazuje e-maile wysyłane na anonimowy adres 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
firebase.auth().currentUser.displayName
Jeśli jednak konto Apple było wcześniej używane do logowania użytkownika w aplikacji bez jeśli używasz Firebase, Apple nie udostępni Firebase wyświetlanej nazwy użytkownika.
Ponowne uwierzytelnianie i łączenie kont
Tego samego wzorca można użyć w atrybutach reauthenticateWithPopup()
i
reauthenticateWithRedirect()
, za pomocą którego możesz pobrać nowe
dane logowania do operacji poufnych, które wymagają ostatniego logowania:
Web
import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth"; // Result from Redirect auth flow. const auth = getAuth(); const provider = new OAuthProvider('apple.com'); reauthenticateWithPopup(auth.currentUser, provider) .then((result) => { // User is re-authenticated with fresh tokens minted and can perform // sensitive operations like account deletion, or updating their email // address or password. // The signed-in user info. const user = result.user; // You can also get the Apple OAuth Access and ID Tokens. const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; // ... }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Web
const provider = new firebase.auth.OAuthProvider('apple.com'); firebase .auth() .currentUser .reauthenticateWithPopup(provider) .then((result) => { // User is re-authenticated with fresh tokens minted and can perform // sensitive operations like account deletion, or updating their email // address or password. /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // The signed-in user info. var user = result.user; // You can also get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // IdP data available in result.additionalUserInfo.profile. // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
Możesz też użyć linkWithPopup()
i linkWithRedirect()
, aby połączyć różne usługi
dostawców tożsamości na istniejących kontach.
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:
Web
import { getAuth, linkWithPopup, FacebookAuthProvider } from "firebase/auth"; const auth = getAuth(); const provider = new FacebookAuthProvider(); provider.addScope('user_birthday'); // Assuming the current user is an Apple user linking a Facebook provider. linkWithPopup(auth.currentUser, provider) .then((result) => { // Facebook credential is linked to the current Apple user. // ... // The user can now sign in to the same account // with either Apple or Facebook. }) .catch((error) => { // Handle error. });
Web
const provider = new firebase.auth.FacebookAuthProvider(); provider.addScope('user_birthday'); // Assuming the current user is an Apple user linking a Facebook provider. firebase.auth().currentUser.linkWithPopup(provider) .then((result) => { // Facebook credential is linked to the current Apple user. // Facebook additional data available in result.additionalUserInfo.profile, // Additional Facebook OAuth access token can also be retrieved. // result.credential.accessToken // The user can now sign in to the same account // with either Apple or Facebook. }) .catch((error) => { // Handle error. });
Uwierzytelnianie za pomocą Firebase w rozszerzeniu do Chrome
Jeśli tworzysz aplikację rozszerzenia do Chrome, zapoznaj się z Przewodnik po dokumentach poza ekranem
Pamiętaj, że i tak musisz zweryfikować domenę niestandardową w Apple, podobnie jak domyślna domena firebaseapp.com:
http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt
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
Aby spełnić to wymaganie, wykonaj następujące czynności:
Pamiętaj, aby wypełnić pola Identyfikator usług i Proces kodu OAuth. konfiguracji sekcji Zaloguj się przez Apple w konfiguracji dostawcy, opisane w artykule Konfigurowanie logowania się przez Apple .
Firebase nie przechowuje tokenów użytkowników tworzonych za pomocą Zaloguj się przez Apple; przed anulowaniem musisz poprosić użytkownika o ponowne zalogowanie się jego token i usunięcie konta.
Następnie uzyskaj token dostępu Apple OAuth ze strony
OAuthCredential
. użyj go do wywołaniarevokeAccessToken(auth, token)
w celu unieważnienia protokołu Apple OAuth token dostępu.const provider = new OAuthProvider('apple.com'); provider.addScope('email'); provider.addScope('name'); const auth = getAuth(); signInWithPopup(auth, provider).then(result => { // Get the Apple OAuth access token. const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; // Revoke the Apple OAuth access token. revokeAccessToken(auth, accessToken) .then(() => { // Token revoked. // Delete the user account. // ... }) .catch(error => { // An error happened. // ... }); });
Na koniec usuń konto użytkownika (i wszystkie powiązane dane).
Zaawansowane: uwierzytelnianie za pomocą Firebase w Node.js
Aby uwierzytelnić się w Firebase w aplikacji Node.js:
Logowanie użytkownika na jego konto Apple i uzyskiwanie jego identyfikatora Apple ID token. Możesz to osiągnąć na kilka sposobów. Jeśli na przykład środowisko Node.js aplikacja ma interfejs przeglądarki:
W backendzie wygeneruj losowy ciąg znaków („jednorazowy”) i oblicz jego Identyfikator SHA256. Jest to jednorazowa wartość służąca do sprawdzania poprawności w obie strony między backendem a serwerami uwierzytelniania Apple.
Web
const crypto = require("crypto"); const string_decoder = require("string_decoder"); // Generate a new random string for each sign-in const generateNonce = (length) => { const decoder = new string_decoder.StringDecoder("ascii"); const buf = Buffer.alloc(length); let nonce = ""; while (nonce.length < length) { crypto.randomFillSync(buf); nonce = decoder.write(buf); } return nonce.slice(0, length); }; const unhashedNonce = generateNonce(10); // SHA256-hashed nonce in hex const hashedNonceHex = crypto.createHash('sha256') .update(unhashedNonce).digest().toString('hex');
Web
const crypto = require("crypto"); const string_decoder = require("string_decoder"); // Generate a new random string for each sign-in const generateNonce = function(length) { const decoder = new string_decoder.StringDecoder("ascii"); const buf = Buffer.alloc(length); var nonce = ""; while (nonce.length < length) { crypto.randomFillSync(buf); nonce = decoder.write(buf); } return nonce.slice(0, length); }; const unhashedNonce = generateNonce(10); // SHA256-hashed nonce in hex const hashedNonceHex = crypto.createHash('sha256') .update(unhashedNonce).digest().toString('hex');
Na stronie logowania podaj zahaszowaną wartość jednorazową w polu Zaloguj się przez Konfiguracja Apple:
<script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script> <div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div> <script> AppleID.auth.init({ clientId: YOUR_APPLE_CLIENT_ID, scope: 'name email', redirectURI: URL_TO_YOUR_REDIRECT_HANDLER, // See the next step. state: '[STATE]', // Optional value that Apple will send back to you // so you can return users to the same context after // they sign in. nonce: HASHED_NONCE // The hashed nonce you generated in the previous step. }); </script>
Pobierz token Apple ID ze strony serwera odpowiedzi POST:
app.post('/redirect', (req, res) => { const savedState = req.cookies.__session; const code = req.body.code; const state = req.body.state; const appleIdToken = req.body.id_token; if (savedState !== state || !code) { res.status(403).send('403: Permission denied'); } else { // Sign in with Firebase using appleIdToken. (See next step). } });
Zobacz też Konfigurowanie strony internetowej pod kątem logowania przez Apple.
Gdy uzyskasz token Apple ID użytkownika, użyj go do utworzenia danych uwierzytelniających i zaloguj się za pomocą danych logowania:
Web
import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth"; const auth = getAuth(); // Build Firebase credential with the Apple ID token. const provider = new OAuthProvider('apple.com'); const authCredential = provider.credential({ idToken: appleIdToken, rawNonce: unhashedNonce, }); // Sign in with credential form the Apple user. signInWithCredential(auth, authCredential) .then((result) => { // User signed in. }) .catch((error) => { // An error occurred. If error.code == 'auth/missing-or-invalid-nonce', // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. console.log(error); });
Web
// Build Firebase credential with the Apple ID token. const provider = new firebase.auth.OAuthProvider('apple.com'); const authCredential = provider.credential({ idToken: appleIdToken, rawNonce: unhashedNonce, }); // Sign in with credential form the Apple user. firebase.auth().signInWithCredential(authCredential) .then((result) => { // User signed in. }) .catch((error) => { // An error occurred. If error.code == 'auth/missing-or-invalid-nonce', // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. console.log(error); });
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.
-
Aby poznać stan uwierzytelniania użytkownika w swoich aplikacjach, ustaw obserwatora na obiekcie
Auth
. Dzięki temu możesz uzyskać dane użytkownika podstawowych informacji o profilu z obiektuUser
. 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
:
Web
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
Web
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });