Authentifizieren Sie sich mit Apple mit JavaScript

Sie können Ihren Benutzern ermöglichen, sich bei Firebase mit ihrer Apple-ID zu authentifizieren, indem Sie das Firebase SDK verwenden, um den End-to-End-OAuth 2.0-Anmeldeablauf auszuführen.

Bevor Sie beginnen

Um Benutzer mit Apple anzumelden, konfigurieren Sie zunächst „Mit Apple anmelden“ auf der Entwickler-Website von Apple und aktivieren Sie dann Apple als Anmeldeanbieter für Ihr Firebase-Projekt.

Treten Sie dem Apple-Entwicklerprogramm bei

Mit Apple anmelden kann nur von Mitgliedern des Apple Developer Program konfiguriert werden.

Konfigurieren Sie die Anmeldung mit Apple

Gehen Sie auf der Apple Developer- Website wie folgt vor:

  1. Verknüpfen Sie Ihre Website mit Ihrer App, wie im ersten Abschnitt von Konfiguration der Anmeldung bei Apple für das Web beschrieben. Wenn Sie dazu aufgefordert werden, registrieren Sie die folgende URL als Rückgabe-URL:

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

    Sie können Ihre Firebase-Projekt-ID auf der Einstellungsseite der Firebase-Konsole abrufen .

    Wenn Sie fertig sind, notieren Sie sich Ihre neue Service-ID, die Sie im nächsten Abschnitt benötigen.

  2. Erstellen Sie eine Anmeldung mit dem privaten Apple-Schlüssel . Im nächsten Abschnitt benötigen Sie Ihren neuen privaten Schlüssel und die Schlüssel-ID.
  3. Wenn Sie eine der Funktionen von Firebase Authentication verwenden, die E-Mails an Benutzer senden, einschließlich E-Mail-Link-Anmeldung, E-Mail-Adressüberprüfung, Widerruf von Kontoänderungen und andere, konfigurieren Sie den privaten Apple-E-Mail- Weiterleitungsdienst und registrieren noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (oder Ihre angepasste E-Mail-Vorlagendomäne), damit Apple von Firebase Authentication gesendete E-Mails an anonymisierte Apple-E-Mail-Adressen weiterleiten kann.

Aktivieren Sie Apple als Anmeldeanbieter

  1. Fügen Sie Ihrem Projekt Firebase hinzu .
  2. Öffnen Sie in der Firebase-Konsole den Abschnitt Auth . Aktivieren Sie auf der Registerkarte Anmeldemethode den Apple -Anbieter. Geben Sie die Service-ID an, die Sie im vorherigen Abschnitt erstellt haben. Geben Sie außerdem im Abschnitt OAuth- Codeflusskonfiguration Ihre Apple-Team-ID sowie den privaten Schlüssel und die Schlüssel-ID an, die Sie im vorherigen Abschnitt erstellt haben.

Erfüllen Sie die Anforderungen von Apple an anonymisierte Daten

Mit Apple anmelden bietet Benutzern die Möglichkeit, ihre Daten, einschließlich ihrer E-Mail-Adresse, bei der Anmeldung zu anonymisieren. Benutzer, die diese Option wählen, haben E-Mail-Adressen mit der Domäne privaterelay.appleid.com . Wenn Sie „Mit Apple anmelden“ in Ihrer App verwenden, müssen Sie alle geltenden Entwicklerrichtlinien oder Bedingungen von Apple in Bezug auf diese anonymisierten Apple-IDs einhalten.

Dazu gehört auch das Einholen der erforderlichen Benutzereinwilligung, bevor Sie direkt identifizierende personenbezogene Daten mit einer anonymisierten Apple-ID verknüpfen. Bei Verwendung der Firebase-Authentifizierung kann dies die folgenden Aktionen umfassen:

  • Verknüpfen Sie eine E-Mail-Adresse mit einer anonymisierten Apple-ID oder umgekehrt.
  • Verknüpfen Sie eine Telefonnummer mit einer anonymisierten Apple-ID oder umgekehrt
  • Verknüpfen Sie einen nicht anonymen Social Credential (Facebook, Google usw.) mit einer anonymisierten Apple ID oder umgekehrt.

Die obige Liste ist nicht vollständig. Lesen Sie die Lizenzvereinbarung für das Apple-Entwicklerprogramm im Abschnitt „Mitgliedschaft“ Ihres Entwicklerkontos, um sicherzustellen, dass Ihre App die Anforderungen von Apple erfüllt.

Behandeln Sie den Anmeldevorgang mit dem Firebase SDK

Wenn Sie eine Web-App erstellen, können Sie Ihre Benutzer am einfachsten mit ihren Apple-Konten bei Firebase authentifizieren, indem Sie den gesamten Anmeldevorgang mit dem Firebase JavaScript SDK abwickeln.

Führen Sie die folgenden Schritte aus, um den Anmeldevorgang mit dem Firebase JavaScript SDK zu verarbeiten:

  1. Erstellen Sie eine Instanz eines OAuthProviders mit der entsprechenden Anbieter-ID apple.com .

    Webversion 9

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

    Webversion 8

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. Optional: Geben Sie zusätzliche OAuth 2.0-Bereiche über den Standard hinaus an, die Sie vom Authentifizierungsanbieter anfordern möchten.

    Webversion 9

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

    Webversion 8

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

    Wenn Ein Konto pro E-Mail-Adresse aktiviert ist, fordert Firebase standardmäßig E-Mail- und Namensbereiche an. Wenn Sie diese Einstellung in Mehrere Konten pro E-Mail-Adresse ändern, fordert Firebase keine Bereiche von Apple an, es sei denn, Sie geben diese an.

  3. Optional: Wenn Sie den Anmeldebildschirm von Apple in einer anderen Sprache als Englisch anzeigen möchten, legen Sie den locale -Parameter fest. Informationen zu den unterstützten Gebietsschemas finden Sie in den Dokumenten zum Anmelden mit Apple .

    Webversion 9

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

    Webversion 8

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. Authentifizieren Sie sich bei Firebase mithilfe des OAuth-Anbieterobjekts. Sie können Ihre Benutzer auffordern, sich mit ihren Apple-Konten anzumelden, indem Sie entweder ein Popup-Fenster öffnen oder auf die Anmeldeseite umleiten. Die Umleitungsmethode wird auf Mobilgeräten bevorzugt.

    • Um sich mit einem Popup-Fenster anzumelden, rufen signInWithPopup() auf:

      Webversion 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.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

      Webversion 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;
      
          // ...
        });
    • Um sich durch Umleitung zur Anmeldeseite anzumelden, rufen signInWithRedirect() :

      Webversion 9

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

      Webversion 8

      firebase.auth().signInWithRedirect(provider);

      Nachdem der Benutzer die Anmeldung abgeschlossen hat und zur Seite zurückgekehrt ist, können Sie das Anmeldeergebnis abrufen, indem getRedirectResult() aufrufen:

      Webversion 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.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

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

      Hier können Sie auch Fehler abfangen und behandeln. Eine Liste der Fehlercodes finden Sie in der API-Referenz .

    Im Gegensatz zu anderen Anbietern, die von Firebase Auth unterstützt werden, stellt Apple keine Foto-URL bereit.

    Wenn der Benutzer sich entscheidet, seine E-Mail-Adresse nicht mit der App zu teilen, stellt Apple eine eindeutige E-Mail-Adresse für diesen Benutzer (in der Form xyz@privaterelay.appleid.com ) bereit, die es mit Ihrer App teilt. Wenn Sie den privaten E-Mail-Weiterleitungsdienst konfiguriert haben, leitet Apple an die anonymisierte Adresse gesendete E-Mails an die echte E-Mail-Adresse des Benutzers weiter.

    Apple teilt Benutzerinformationen wie den Anzeigenamen nur mit Apps, wenn sich ein Benutzer zum ersten Mal anmeldet. Normalerweise speichert Firebase den Anzeigenamen, wenn sich ein Benutzer zum ersten Mal bei Apple anmeldet, den Sie mit firebase.auth().currentUser.displayName . Wenn Sie jedoch zuvor Apple verwendet haben, um einen Benutzer bei der App anzumelden, ohne Firebase zu verwenden, stellt Apple Firebase nicht den Anzeigenamen des Benutzers bereit.

Erneute Authentifizierung und Kontoverknüpfung

Dasselbe Muster kann mit reauthenticateWithPopup() und reauthenticateWithRedirect() verwendet werden, mit denen Sie neue Anmeldeinformationen für vertrauliche Vorgänge abrufen können, die eine kürzlich erfolgte Anmeldung erfordern:

Webversion 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.email;
    // The credential that was used.
    const credential = OAuthProvider.credentialFromError(error);

    // ...
  });

Webversion 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;

    // ...
  });

Und Sie können linkWithPopup() und linkWithRedirect() verwenden, um verschiedene Identitätsanbieter mit bestehenden Konten zu verknüpfen.

Beachten Sie, dass Apple verlangt, dass Sie die ausdrückliche Zustimmung der Benutzer einholen, bevor Sie ihre Apple-Konten mit anderen Daten verknüpfen.

Um beispielsweise ein Facebook-Konto mit dem aktuellen Firebase-Konto zu verknüpfen, verwenden Sie das Zugriffstoken, das Sie erhalten haben, als Sie den Benutzer bei Facebook angemeldet haben:

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

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

Authentifizieren Sie sich mit Firebase in einer Chrome-Erweiterung

Wenn Sie eine Chrome-Erweiterungs-App erstellen, müssen Sie Ihre Chrome-Erweiterungs-ID hinzufügen:

  1. Öffnen Sie Ihr Projekt in der Firebase-Konsole .
  2. Öffnen Sie im Abschnitt Authentifizierung die Seite Anmeldemethode .
  3. Fügen Sie der Liste der autorisierten Domänen einen URI wie den folgenden hinzu:
    chrome-extension://CHROME_EXTENSION_ID

Für Chrome-Erweiterungen sind nur Popup-Vorgänge ( signInWithPopup , linkWithPopup und reauthenticateWithPopup ) verfügbar, da Chrome-Erweiterungen keine HTTP-Weiterleitungen verwenden können. Sie sollten diese Methoden von einem Hintergrundseitenskript und nicht von einem Browseraktions-Popup aufrufen, da das Authentifizierungs-Popup das Browseraktions-Popup abbricht. Die Popup-Methoden dürfen nur in Erweiterungen mit Manifest V2 verwendet werden. Das neuere Manifest V3 erlaubt nur Hintergrundskripte in Form von Service Workern, die die Popup-Operationen gar nicht durchführen können.

Stellen Sie in der Manifestdatei Ihrer Chrome-Erweiterung sicher, dass Sie die URL https://apis.google.com zur Zulassungsliste content_security_policy hinzufügen.

Beachten Sie, dass Sie die benutzerdefinierte Domäne weiterhin bei Apple verifizieren müssen, ähnlich wie bei der Standarddomäne firebaseapp.com:

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

Erweitert: Authentifizieren Sie sich mit Firebase in Node.js

So authentifizieren Sie sich bei Firebase in einer Node.js-Anwendung:

  1. Melden Sie den Benutzer mit seinem Apple-Konto an und erhalten Sie das Apple-ID-Token des Benutzers. Sie können dies auf verschiedene Weise erreichen. Wenn Ihre Node.js-App beispielsweise über ein Browser-Frontend verfügt:

    1. Generieren Sie in Ihrem Back-End eine zufällige Zeichenfolge (eine „Nonce“) und berechnen Sie deren SHA256-Hash. Die Nonce ist ein einmaliger Verwendungswert, den Sie verwenden, um einen einzelnen Roundtrip zwischen Ihrem Back-End und den Authentifizierungsservern von Apple zu validieren.

      Webversion 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.substr(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');

      Webversion 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.substr(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');
    2. Geben Sie auf Ihrer Anmeldeseite die gehashte Nonce in Ihrer Konfiguration „Mit Apple anmelden“ an:

      <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. Holen Sie sich das Apple-ID-Token von der POSTed-Authentifizierungsantwort auf der Serverseite:

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

    Siehe auch Konfigurieren Ihrer Webseite für die Anmeldung mit Apple .

  2. Nachdem Sie das Apple-ID-Token des Benutzers erhalten haben, verwenden Sie es, um ein Credential-Objekt zu erstellen, und melden Sie sich dann mit dem Credential an:

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

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

Nächste Schritte

Nachdem sich ein Benutzer zum ersten Mal angemeldet hat, wird ein neues Benutzerkonto erstellt und mit den Anmeldeinformationen verknüpft – d. h. dem Benutzernamen und Kennwort, der Telefonnummer oder den Authentifizierungsanbieterinformationen –, mit denen sich der Benutzer angemeldet hat. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Benutzer in jeder App in Ihrem Projekt zu identifizieren, unabhängig davon, wie sich der Benutzer anmeldet.

  • In Ihren Apps besteht die empfohlene Möglichkeit, den Authentifizierungsstatus Ihres Benutzers zu erfahren, darin, einen Beobachter für das Auth festzulegen. Sie können dann die grundlegenden Profilinformationen des Benutzers aus dem User abrufen. Siehe Benutzer verwalten .

  • In Ihren Sicherheitsregeln für die Firebase-Echtzeitdatenbank und den Cloud-Speicher können Sie die eindeutige Benutzer-ID des angemeldeten Benutzers aus der Variablen auth und damit steuern, auf welche Daten ein Benutzer zugreifen kann.

Sie können Benutzern erlauben, sich mit mehreren Authentifizierungsanbietern bei Ihrer App anzumelden, indem Sie die Anmeldeinformationen des Authentifizierungsanbieters mit einem vorhandenen Benutzerkonto verknüpfen.

Um einen Benutzer abzumelden, rufen signOut :

Webversion 9

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

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

Webversion 8

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