Uwierzytelnij za pomocą Apple z JavaScript

Możesz zezwolić użytkownikom na uwierzytelnianie w Firebase przy użyciu ich Apple ID, używając pakietu Firebase SDK do przeprowadzania kompleksowego procesu logowania OAuth 2.0.

Zanim zaczniesz

Aby logować użytkowników za pomocą Apple, najpierw skonfiguruj Zaloguj się za pomocą Apple w witrynie programisty Apple, a następnie włącz Apple jako dostawcę logowania do projektu Firebase.

Dołącz do programu dla programistów Apple

Funkcja logowania za pomocą Apple może być konfigurowana tylko przez członków programu Apple Developer Program .

Skonfiguruj Zaloguj się za pomocą Apple

W witrynie Apple Developer wykonaj następujące czynności:

  1. Powiąż swoją witrynę internetową z aplikacją zgodnie z opisem w pierwszej sekcji Konfiguruj logowanie za pomocą Apple dla sieci Web . Po wyświetleniu monitu zarejestruj następujący adres URL jako zwrotny adres URL:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Identyfikator projektu Firebase możesz uzyskać na stronie ustawień konsoli Firebase .

    Po zakończeniu zanotuj swój nowy identyfikator usługi, który będzie Ci potrzebny w następnej sekcji.

  2. Utwórz Zaloguj się przy użyciu klucza prywatnego Apple . W następnej sekcji będziesz potrzebować nowego klucza prywatnego i identyfikatora klucza.
  3. Jeśli korzystasz z dowolnej funkcji uwierzytelniania Firebase, która umożliwia wysyłanie wiadomości e-mail do użytkowników, w tym logowania się za pomocą łącza do poczty e-mail, weryfikacji adresu e-mail, cofnięcia zmiany konta i innych, skonfiguruj usługę przekazywania prywatnych wiadomości e-mail Apple i zarejestruj noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (lub dostosowanej domeny szablonu wiadomości e-mail), dzięki czemu Apple może przekazywać wiadomości e-mail wysyłane przez uwierzytelnianie Firebase na anonimowe adresy e-mail Apple.

Włącz Apple jako dostawcę logowania

  1. Dodaj Firebase do swojego projektu .
  2. W konsoli Firebase otwórz sekcję Auth . Na karcie Metoda logowania włącz dostawcę Apple . Podaj identyfikator usługi utworzony w poprzedniej sekcji. Ponadto w sekcji konfiguracji przepływu kodu OAuth określ identyfikator zespołu Apple oraz klucz prywatny i identyfikator klucza utworzony w poprzedniej sekcji.

Przestrzegaj wymagań Apple dotyczących anonimowych danych

Zaloguj się za pomocą Apple daje użytkownikom możliwość anonimizacji swoich danych, w tym adresu e-mail, podczas logowania. Użytkownicy, którzy wybiorą tę opcję, mają adresy e-mail z domeną privaterelay.appleid.com . Korzystając z funkcji Zaloguj się przez Apple w swojej aplikacji, musisz przestrzegać wszelkich obowiązujących zasad lub warunków dla programistów Apple dotyczących tych anonimowych identyfikatorów Apple ID.

Obejmuje to uzyskanie wymaganej zgody użytkownika przed powiązaniem jakichkolwiek bezpośrednio identyfikujących danych osobowych z anonimowym identyfikatorem Apple ID. Podczas korzystania z Uwierzytelniania Firebase może to obejmować następujące czynności:

  • Połącz adres e-mail z anonimowym identyfikatorem Apple ID lub odwrotnie.
  • Połącz numer telefonu z anonimowym identyfikatorem Apple ID lub odwrotnie
  • Połącz nieanonimowe dane logowania społecznościowego (Facebook, Google itp.) z anonimowym identyfikatorem Apple ID lub odwrotnie.

Powyższa lista nie jest wyczerpująca. Zapoznaj się z Umową licencyjną programu Apple Developer w sekcji Członkostwo swojego konta programisty, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.

Obsługuj proces logowania za pomocą pakietu Firebase SDK

Jeśli tworzysz aplikację internetową, najłatwiejszym sposobem uwierzytelnienia użytkowników w Firebase przy użyciu 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 następujące czynności:

  1. Utwórz wystąpienie OAuthProvider przy użyciu odpowiedniego identyfikatora dostawcy apple.com .

    Web version 9

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('apple.com');

    Web version 8

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. Opcjonalnie: określ dodatkowe zakresy OAuth 2,0 poza zakresem domyślnym, którego chcesz zażądać od dostawcy uwierzytelniania.

    Web version 9

    provider.addScope('email');
    provider.addScope('name');

    Web version 8

    provider.addScope('email');
    provider.addScope('name');

    Domyślnie, gdy jedno konto na adres e-mail jest włączone, Firebase żąda zakresów adresów e-mail i nazw. Jeśli zmienisz to ustawienie na Wiele kont na adres e-mail , Firebase nie zażąda żadnych zakresów od Apple, chyba że je określisz.

  3. Opcjonalnie: jeśli chcesz wyświetlić ekran logowania Apple w języku innym niż angielski, ustaw parametr locale . Obsługiwane języki można znaleźć w dokumencie Zaloguj się za pomocą Apple .

    Web version 9

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });

    Web version 8

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. Uwierzytelnij się w Firebase przy użyciu obiektu dostawcy OAuth. Możesz poprosić użytkowników o zalogowanie się na swoje konta Apple, otwierając wyskakujące okienko lub przekierowując do strony logowania. Metoda przekierowania jest preferowana na urządzeniach mobilnych.

    • Aby zalogować się za pomocą wyskakującego okna, wywołaj signInWithPopup() :

      Web version 9

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

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

      Web version 9

      import { getAuth, signInWithRedirect } from "firebase/auth";
      
      const auth = getAuth();
      signInWithRedirect(auth, provider);

      Web version 8

      firebase.auth().signInWithRedirect(provider);

      Gdy użytkownik zakończy logowanie i wróci na stronę, możesz uzyskać wynik logowania, wywołując getRedirectResult() :

      Web version 9

      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 version 8

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

      Tutaj też możesz wyłapać i obsłużyć błędy. Listę kodów błędów można znaleźć w dokumentacji API .

    W przeciwieństwie do innych dostawców obsługiwanych przez Firebase Auth, Apple nie udostępnia adresu URL zdjęcia.

    Ponadto, gdy użytkownik zdecyduje się nie udostępniać swojego adresu e-mail aplikacji, Apple przydziela mu unikalny adres e-mail (w postaci xyz@privaterelay.appleid.com ), który udostępnia Twojej aplikacji. Jeśli skonfigurowałeś usługę przekazywania prywatnych wiadomości e-mail, Apple przekazuje wiadomości e-mail wysyłane na anonimowy adres na prawdziwy adres e-mail użytkownika.

    Firma Apple udostępnia aplikacjom informacje o użytkowniku, takie jak nazwa wyświetlana, tylko przy pierwszym logowaniu użytkownika. Zwykle Firebase przechowuje nazwę wyświetlaną przy pierwszym logowaniu użytkownika do firmy Apple, którą można uzyskać za pomocą firebase.auth().currentUser.displayName . Jeśli jednak wcześniej logowałeś użytkownika do aplikacji za pomocą Apple bez użycia Firebase, Apple nie udostępni Firebase nazwy wyświetlanej użytkownika.

Ponowne uwierzytelnianie i łączenie kont

Ten sam wzorzec może być użyty z reauthenticateWithPopup() i reauthenticateWithRedirect() , których można użyć do pobrania nowego poświadczenia dla wrażliwych operacji, które wymagają niedawnego logowania:

Web version 9

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 version 8

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;

    // ...
  })
  .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 Apple wymaga uzyskania wyraźnej zgody użytkowników przed połączeniem ich kont Apple z innymi danymi.

Na przykład, aby połączyć konto Facebook z bieżącym kontem Firebase, użyj tokena dostępu, który otrzymałeś po zalogowaniu użytkownika do Facebooka:

Web version 9

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 version 8

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

Uwierzytelnij się w Firebase w rozszerzeniu Chrome

Jeśli tworzysz aplikację rozszerzenia do Chrome, musisz dodać swój identyfikator rozszerzenia do Chrome:

  1. Otwórz projekt w konsoli Firebase .
  2. W sekcji Uwierzytelnianie otwórz stronę Metoda logowania .
  3. Dodaj identyfikator URI podobny do poniższego do listy autoryzowanych domen:
    chrome-extension://CHROME_EXTENSION_ID

W rozszerzeniach Chrome dostępne są tylko operacje wyskakujące ( signInWithPopup , linkWithPopup i reauthenticateWithPopup ), ponieważ rozszerzenia Chrome nie mogą korzystać z przekierowań HTTP. Powinieneś wywoływać te metody ze skryptu strony w tle, a nie z wyskakującego okienka akcji przeglądarki, ponieważ wyskakujące okienko uwierzytelniania anuluje wyskakujące okienko akcji przeglądarki. Metody wyskakujące mogą być używane tylko w rozszerzeniach korzystających z Manifest V2 . Nowszy Manifest V3 dopuszcza jedynie skrypty działające w tle w postaci pracowników usług, które w ogóle nie mogą wykonywać operacji wyskakujących okienek.

W pliku manifestu rozszerzenia do Chrome upewnij się, że dodajesz adres URL https://apis.google.com do listy dozwolonych content_security_policy .

Pamiętaj, że nadal musisz zweryfikować domenę niestandardową w Apple, podobnie jak w przypadku domyślnej domeny firebaseapp.com:

http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt

Zaawansowane: uwierzytelnianie za pomocą Firebase w Node.js

Aby uwierzytelnić się za pomocą Firebase w aplikacji Node.js:

  1. Zaloguj się użytkownika za pomocą jego konta Apple i uzyskaj token Apple ID użytkownika. Możesz to osiągnąć na kilka sposobów. Na przykład, jeśli Twoja aplikacja Node.js ma interfejs przeglądarki:

    1. Na swoim zapleczu wygeneruj losowy ciąg („nonce”) i oblicz jego hash SHA256. Jednorazowa wartość jest jednorazową wartością używaną do walidacji pojedynczej podróży w obie strony między backendem a serwerami uwierzytelniającymi Apple.

      Web version 9

      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 version 8

      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');
    2. Na stronie logowania podaj zaszyfrowany numer 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>
      
    3. Uzyskaj token Apple ID po stronie serwera odpowiedzi POSTed auth:

      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 także Konfigurowanie swojej strony internetowej do logowania się za pomocą Apple .

  2. Po otrzymaniu tokena Apple ID użytkownika użyj go do zbudowania obiektu Credential, a następnie zaloguj się użytkownika za pomocą poświadczenia:

    Web version 9

    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 version 8

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

Następne kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z poświadczeniami — czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania — za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane jako część projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się on loguje.

  • W aplikacjach zalecanym sposobem poznania stanu uwierzytelniania użytkownika jest ustawienie obserwatora na obiekcie Auth . Następnie można uzyskać podstawowe informacje o profilu użytkownika z obiektu User . Zobacz Zarządzanie użytkownikami .

  • W regułach bezpieczeństwa bazy danych czasu rzeczywistego i usługi Cloud Storage Firebase możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i używać go do kontrolowania, do jakich danych użytkownik może uzyskać dostęp.

Możesz zezwolić użytkownikom na logowanie się do Twojej aplikacji przy użyciu wielu dostawców uwierzytelniania, łącząc poświadczenia dostawcy uwierzytelniania z istniejącym kontem użytkownika.

Aby wylogować użytkownika, zadzwoń do signOut :

Web version 9

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web version 8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});