Możesz zezwolić użytkownikom na uwierzytelnianie w Firebase za pomocą Apple ID, korzystając z pakietu Firebase SDK do przeprowadzania kompleksowego procesu logowania OAuth 2.0.
Zanim zaczniesz
Aby logować użytkowników za pomocą Apple, najpierw skonfiguruj logowanie przez Apple na stronie dla deweloperów Apple, a potem włącz Apple jako dostawcę logowania w projekcie Firebase.
Dołączanie do programu Apple Developer Program
Logowanie przez Apple mogą konfigurować tylko uczestnicy programu Apple Developer.
Konfigurowanie logowania się przez Apple
Na stronie Apple Developer wykonaj te czynności:
-
Powiąż swoją witrynę z aplikacją zgodnie z opisem w pierwszej sekcji artykułu Konfigurowanie logowania za pomocą Apple w internecie. Gdy pojawi się prośba, zarejestruj ten adres URL jako powrotny adres URL:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
Identyfikator projektu Firebase znajdziesz na stronie ustawień Firebase konsoli.
Gdy skończysz, zanotuj nowy identyfikator usługi, który będzie Ci potrzebny w następnej sekcji.
- Utwórz klucz prywatny funkcji Zaloguj się przez Apple. W następnej sekcji będziesz potrzebować nowego klucza prywatnego i identyfikatora klucza.
-
Jeśli korzystasz z funkcji Firebase Authentication, które wysyłają e-maile do użytkowników, w tym logowania za pomocą linku w e-mailu, weryfikacji adresu e-mail, wycofania zmiany konta i innych, skonfiguruj prywatną usługę przekaźnika poczty e-mail Apple i zarejestruj
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com
(lub dostosowaną domenę szablonu e-maila), aby Apple mogło przekazywać e-maile wysyłane przez Firebase Authentication na anonimowe adresy e-mail Apple.
Włączanie Apple jako dostawcy logowania
- Dodaj Firebase do projektu.
- W Firebasekonsoli otwórz sekcję Uwierzytelnianie. Na karcie Metoda logowania włącz dostawcę Apple. Określ identyfikator usługi utworzony w poprzedniej sekcji. W sekcji konfiguracji procesu OAuth podaj też identyfikator zespołu Apple, klucz prywatny i identyfikator klucza utworzone w poprzedniej sekcji.
Zapewnianie zgodności z wymaganiami Apple dotyczącymi danych anonimizowanych
Logowanie przez Apple umożliwia użytkownikom anonimizację danych, w tym adresu e-mail, podczas logowania. Użytkownicy, którzy wybiorą tę opcję, będą mieć adresy e-mail z domeną privaterelay.appleid.com
. Jeśli w aplikacji używasz funkcji Zaloguj się przez Apple, musisz przestrzegać wszelkich obowiązujących zasad lub warunków dla deweloperów firmy Apple dotyczących tych zanonimizowanych identyfikatorów Apple.
Obejmuje to uzyskanie wymaganej zgody użytkownika przed powiązaniem bezpośrednio identyfikujących danych osobowych z zanonimizowanym identyfikatorem Apple ID. W przypadku korzystania z Uwierzytelniania Firebase mogą to być te działania:
- Połącz adres e-mail z anonimizowanym identyfikatorem Apple ID lub odwrotnie.
- Łączenie numeru telefonu z zanonimizowanym identyfikatorem Apple ID i odwrotnie
- połączenie nieanonimowych danych logowania w usługach społecznościowych (Facebook, Google itp.) ze zanonimizowanym identyfikatorem Apple ID lub odwrotnie;
Powyższa lista nie jest wyczerpująca. Zapoznaj się z umową licencyjną programu Apple Developer Program w sekcji Członkostwo na koncie dewelopera, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.
Obsługa procesu logowania za pomocą pakietu Firebase SDK
Jeśli tworzysz aplikację internetową, najprostszym sposobem uwierzytelniania użytkowników w Firebase za pomocą ich kont Apple jest obsługa całego procesu logowania za pomocą pakietu Firebase JavaScript SDK.
Aby obsłużyć proces logowania za pomocą pakietu Firebase JavaScript SDK, wykonaj te czynności:
Utwórz instancję OAuthProvider, używając odpowiedniego identyfikatora 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 poza domyślnymi, o które chcesz poprosić dostawcę uwierzytelniania.
Web
provider.addScope('email'); provider.addScope('name');
Web
provider.addScope('email'); provider.addScope('name');
Gdy opcja Jedno konto na każdy adres e-mail jest włączona, Firebase domyślnie wysyła prośby o zakresy adresu e-mail i imienia. Jeśli zmienisz to ustawienie na Wiele kont na adres e-mail, Firebase nie będzie wysyłać do Apple żadnych zakresów, chyba że je określisz.
Opcjonalnie: jeśli chcesz, aby ekran logowania Apple był wyświetlany w języku innym niż angielski, ustaw parametr
locale
. Listę obsługiwanych ustawień regionalnych znajdziesz w dokumentacji Logowania przez Apple.Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Uwierzytelnij w Firebase za pomocą obiektu dostawcy OAuth. Możesz poprosić użytkowników o zalogowanie się za pomocą kont Apple, otwierając wyskakujące okienko lub przekierowując ich na stronę logowania. Na urządzeniach mobilnych preferowana jest metoda przekierowania.
Aby zalogować się w wyskakującym okienku, wywołaj funkcję
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ę przez przekierowanie na stronę logowania, wywołaj funkcję
signInWithRedirect()
:
Podczas korzystania z elementów
signInWithRedirect
,linkWithRedirect
lubreauthenticateWithRedirect
stosuj sprawdzone metody.Web
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
Web
firebase.auth().signInWithRedirect(provider);
Gdy użytkownik zakończy logowanie i wróci na stronę, możesz uzyskać wynik logowania, wywołując metodę
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; // ... });
W tym miejscu możesz też wykrywać i obsługiwać błędy. Listę kodów błędów znajdziesz w dokumentacji interfejsu API.
W przeciwieństwie do innych dostawców obsługiwanych przez Firebase Auth Apple nie udostępnia adresu URL zdjęcia.
Gdy użytkownik zdecyduje się nie udostępniać aplikacji swojego adresu e-mail, Apple udostępnia mu unikalny adres e-mail (w formacie
xyz@privaterelay.appleid.com
), który jest udostępniany Twojej aplikacji. Jeśli skonfigurujesz prywatną usługę przekaźnika poczty e-mail, Apple będzie przekazywać e-maile wysyłane na anonimowy adres na prawdziwy adres e-mail użytkownika.Apple udostępnia aplikacjom informacje o użytkowniku, takie jak nazwa wyświetlana, tylko przy pierwszym logowaniu. Zwykle Firebase zapisuje nazwę wyświetlaną przy pierwszym logowaniu użytkownika za pomocą Apple. Możesz ją uzyskać za pomocą
firebase.auth().currentUser.displayName
. Jeśli jednak wcześniej użytkownik logował się w aplikacji za pomocą Apple bez użycia Firebase, Apple nie przekaże Firebase nazwy wyświetlanej użytkownika.
Ponowne uwierzytelnianie i łączenie kont
Ten sam wzorzec można zastosować w przypadku pól reauthenticateWithPopup()
i reauthenticateWithRedirect()
, których możesz użyć do pobrania nowych danych logowania w przypadku operacji wymagających niedawnego zalogowania:
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óżnych dostawców tożsamości z istniejącymi kontami.
Pamiętaj, że firma Apple wymaga uzyskania wyraźnej zgody użytkowników przed połączeniem ich kont Apple z innymi danymi.
Aby na przykład połączyć konto Facebook z bieżącym kontem Firebase, użyj tokena dostępu uzyskanego podczas logowania 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 przewodnikiem po dokumentach poza ekranem.
Pamiętaj, że musisz potwierdzić własność domeny niestandardowej w Apple w podobny sposób jak w przypadku domeny domyślnej firebaseapp.com:
http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt
Unieważnienie tokena
Zgodnie z wytycznymi dotyczącymi weryfikacji aplikacji w App Store firma Apple wymaga, aby aplikacje, które umożliwiają tworzenie kont, pozwalały użytkownikom na rozpoczęcie procesu usuwania konta w aplikacji.
Aby spełnić to wymaganie, wykonaj te czynności:
Upewnij się, że w sekcji Identyfikator usług i Konfiguracja procedury kodu OAuth konfiguracji dostawcy logowania Apple podano wszystkie wymagane informacje zgodnie z opisem w sekcji Konfigurowanie logowania Apple.
Firebase nie przechowuje tokenów użytkowników, gdy są oni tworzeni za pomocą funkcji Logowanie przez Apple. Zanim unieważnisz token użytkownika i usuniesz jego konto, musisz poprosić go o ponowne zalogowanie się.
Następnie uzyskaj token dostępu OAuth Apple z
OAuthCredential
i użyj go do wywołaniarevokeAccessToken(auth, token)
, aby cofnąć token dostępu OAuth Apple.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 z nim dane).
Zaawansowane: uwierzytelnianie w Firebase w Node.js
Aby uwierzytelnić się w Firebase w aplikacji Node.js:
Zaloguj użytkownika za pomocą jego konta Apple i uzyskaj token identyfikatora Apple ID użytkownika. Możesz to zrobić na kilka sposobów. Jeśli na przykład aplikacja Node.js ma interfejs przeglądarki:
W backendzie wygeneruj losowy ciąg znaków („nonce”) i oblicz jego hasz SHA256. Wartość nonce jest używana jednorazowo do weryfikowania pojedynczej wymiany danych 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 zaszyfrowany ciąg jednorazowy w konfiguracji logowania za pomocą 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 z odpowiedzi autoryzacji przesłanej metodą POST po stronie serwera:
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 na potrzeby logowania za pomocą Apple.
Po uzyskaniu tokena identyfikatora Apple użytkownika użyj go do utworzenia obiektu Credential, a następnie zaloguj użytkownika za pomocą tych 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, zostanie utworzone nowe konto użytkownika i powiązane z danymi logowania, czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania, za pomocą których użytkownik się zalogował. Nowe konto jest przechowywane w projekcie Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od sposobu logowania.
-
Zalecanym sposobem sprawdzania stanu autoryzacji użytkownika w aplikacjach jest ustawienie obserwatora na obiekcie
Auth
. Następnie możesz pobrać podstawowe informacje o profilu użytkownika z obiektuUser
. Zobacz Zarządzanie użytkownikami. W Firebase Realtime Database i Cloud Storage regułach bezpieczeństwa możesz pobrać unikalny identyfikator zalogowanego użytkownika ze zmiennej
auth
i użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.
Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą wielu dostawców uwierzytelniania, łącząc dane logowania dostawcy uwierzytelniania z istniejącym kontem użytkownika.
Aby wylogować użytkownika, wywołaj funkcję
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. });