Mit JavaScript über Apple authentifizieren

Sie können Ihren Nutzern die Authentifizierung mit Firebase über ihre Apple-ID ermöglichen. Verwenden Sie dazu das Firebase SDK, um den OAuth 2.0-Anmeldevorgang von Anfang bis Ende auszuführen.

Hinweis

Wenn Sie Nutzern die Anmeldung über Apple ermöglichen möchten, konfigurieren Sie zuerst „Über Apple anmelden“ auf der Entwicklerwebsite von Apple und aktivieren Sie dann Apple als Anmeldeanbieter für Ihr Firebase-Projekt.

Am Apple Developer Program teilnehmen

„Über Apple anmelden“ kann nur von Mitgliedern des Apple Developer Program konfiguriert werden.

„Über Apple anmelden“ konfigurieren

Gehen Sie auf der Apple Developer-Website so vor:

  1. Verknüpfen Sie Ihre Website mit Ihrer App, wie im ersten Abschnitt von „Über Apple anmelden“ für das Web konfigurieren beschrieben. Registrieren Sie die folgende URL als Rückgabe-URL, wenn Sie dazu aufgefordert werden:

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

    Ihre Firebase-Projekt-ID finden Sie in den Einstellungen > Tab Allgemein der Firebase Console.

    Notieren Sie sich die neue Dienst-ID. Sie benötigen sie im nächsten Abschnitt.

  2. Erstellen Sie einen privaten Schlüssel für „ Über Apple anmelden“. Sie benötigen den neuen privaten Schlüssel und die Schlüssel ID im nächsten Abschnitt.
  3. Wenn Sie Funktionen von Firebase Authentication verwenden, mit denen E‑Mails an Nutzer gesendet werden, z. B. die Anmeldung per E‑Mail-Link, die Bestätigung der E‑Mail-Adresse oder den Widerruf von Kontoänderungen, konfigurieren Sie den privaten E‑Mail-Relay-Dienst von Apple und registrieren Sie noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com (oder Ihre benutzerdefinierte E‑Mail-Vorlagendomain). So kann Apple E‑Mails, die von Firebase Authentication gesendet werden, an anonymisierte Apple-E‑Mail-Adressen weiterleiten.

Apple als Anmeldeanbieter aktivieren

  1. Fügen Sie Ihrem Projekt Firebase hinzu.
  2. Wechseln Sie in der Firebase Console zu Security > Authentication.
  3. Aktivieren Sie auf dem Tab Anmeldemethode den Anmeldeanbieter Apple sign-in provider. Geben Sie die Dienst-ID an, die Sie im vorherigen Abschnitt erstellt haben. Geben Sie im Bereich Konfiguration des OAuth-Codeflusses außerdem Ihre Apple-Team-ID sowie den privaten Schlüssel und die Schlüssel-ID an, die Sie im vorherigen Abschnitt erstellt haben.

Anforderungen von Apple an anonymisierte Daten einhalten

Mit „Über Apple anmelden“ können Nutzer ihre Daten, einschließlich ihrer E‑Mail-Adresse, bei der Anmeldung anonymisieren. Nutzer, die diese Option auswählen, haben E‑Mail-Adressen mit der Domain privaterelay.appleid.com. Wenn Sie „Über Apple anmelden“ in Ihrer App verwenden, müssen Sie alle geltenden Entwicklerrichtlinien oder ‑bedingungen von Apple bezüglich dieser anonymisierten Apple-IDs einhalten.

Dazu gehört, dass Sie die erforderliche Nutzereinwilligung einholen müssen, bevor Sie direkt identifizierbare personenbezogene Daten mit einer anonymisierten Apple-ID verknüpfen. Bei der Verwendung von Firebase Authentication können folgende Aktionen erforderlich sein:

  • Eine E‑Mail-Adresse mit einer anonymisierten Apple-ID verknüpfen oder umgekehrt
  • Eine Telefonnummer mit einer anonymisierten Apple-ID verknüpfen oder umgekehrt
  • Anmeldedaten für ein nicht anonymes soziales Netzwerk (z. B. Facebook oder Google) mit einer anonymisierten Apple-ID verknüpfen oder umgekehrt

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

Anmeldevorgang mit dem Firebase SDK verarbeiten

Wenn Sie eine Web-App entwickeln, ist die einfachste Möglichkeit, Ihre Nutzer mit Firebase über ihre Apple-Konten zu authentifizieren, den gesamten Anmeldevorgang mit dem Firebase JavaScript SDK zu verarbeiten.

So verarbeiten Sie den Anmeldevorgang mit dem Firebase JavaScript SDK:

  1. Erstellen Sie eine Instanz von OAuthProvider mit der entsprechenden Anbieter-ID apple.com.

    Web

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

    Web

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

    Web

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

    Web

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

    Wenn Ein Konto pro E‑Mail-Adresse aktiviert ist, fordert Firebase standardmäßig die Bereiche „E‑Mail“ und „Name“ 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 sie an.

  3. Optional:Wenn Sie den Anmeldebildschirm von Apple in einer anderen Sprache als Englisch anzeigen möchten, legen Sie den Parameter locale fest. Informationen zu den unterstützten Gebietsschemas finden Sie in der Dokumentation zu „Über Apple anmelden“.

    Web

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

    Web

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. Authentifizieren Sie sich mit dem OAuth-Anbieterobjekt bei Firebase. Sie können Ihre Nutzer auffordern, sich mit ihren Apple-Konten anzumelden, indem Sie entweder ein Pop‑up-Fenster öffnen oder zu der Anmeldeseite weiterleiten. Die Weiterleitungsmethode wird auf Mobilgeräten bevorzugt.

    • Wenn Sie sich mit einem Pop‑up-Fenster anmelden möchten, rufen Sie signInWithPopup() auf:

      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;
      
          // ...
        });
    • Wenn Sie sich anmelden möchten, indem Sie zur Anmeldeseite weitergeleitet werden, rufen Sie signInWithRedirect() auf:

    Beachten Sie die Best Practices für die Verwendung von signInWithRedirect, linkWithRedirect, oder reauthenticateWithRedirect.

    Web

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

    Web

    firebase.auth().signInWithRedirect(provider);

    Nachdem sich der Nutzer angemeldet und zur Seite zurückgekehrt ist, können Sie das Anmeldeergebnis mit getRedirectResult() abrufen:

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

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

    Im Gegensatz zu anderen von Firebase Authentication unterstützten Anbietern stellt Apple keine Foto-URL zur Verfügung.

    Wenn der Nutzer außerdem seine E‑Mail-Adresse nicht für die App freigeben möchte, stellt Apple eine eindeutige E‑Mail-Adresse für diesen Nutzer bereit (im Format xyz@privaterelay.appleid.com), die für Ihre App freigegeben wird. Wenn Sie den privaten E‑Mail-Relay-Dienst konfiguriert haben, leitet Apple E‑Mails, die an die anonymisierte Adresse gesendet werden, an die tatsächliche E‑Mail-Adresse des Nutzers weiter.

    Apple gibt Nutzerinformationen wie den Anzeigenamen nur beim ersten Anmelden eines Nutzers für Apps frei. Normalerweise speichert Firebase den Anzeigenamen, wenn sich ein Nutzer zum ersten Mal mit Apple anmeldet. Sie können ihn mit firebase.auth().currentUser.displayName abrufen. Wenn Sie Apple jedoch zuvor verwendet haben, um einen Nutzer ohne Firebase in der App anzumelden, stellt Apple Firebase den Anzeigenamen des Nutzers nicht zur Verfügung.

Erneute Authentifizierung und Kontoverknüpfung

Dasselbe Muster kann mit reauthenticateWithPopup() und reauthenticateWithRedirect() verwendet werden. Damit können Sie neue Anmeldedaten für sensible Vorgänge abrufen, für die eine aktuelle Anmeldung erforderlich ist:

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;

    // ...
  });

Mit linkWithPopup() und linkWithRedirect() können Sie verschiedene Identitätsanbieter mit bestehenden Konten verknüpfen.

Apple setzt voraus, dass Sie die ausdrückliche Einwilligung der Nutzer einholen, bevor Sie ihre Apple-Konten mit anderen Daten verknüpfen.

Wenn Sie beispielsweise ein Facebook-Konto mit dem aktuellen Firebase-Konto verknüpfen möchten, verwenden Sie das Zugriffstoken, das Sie durch die Anmeldung des Nutzers bei Facebook erhalten haben:

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

Authentifizierung mit Firebase in einer Chrome-Erweiterung

Wenn Sie eine Chrome-Erweiterungs-App entwickeln, lesen Sie die Anleitung zu Offscreen-Dokumenten.

Sie müssen die benutzerdefinierte Domain weiterhin auf ähnliche Weise bei Apple bestätigen wie die Standarddomain firebaseapp.com:

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

Tokenwiderruf

Apple setzt voraus, dass Apps, die die Kontoerstellung unterstützen, Nutzern die Möglichkeit bieten, das Löschen ihres Kontos innerhalb der App zu initiieren . Das ist in den App Store-Überprüfungs richtlinien beschrieben.

So erfüllen Sie diese Anforderung:

  1. Achten Sie darauf, dass Sie die Bereiche Dienst-ID und Konfiguration des OAuth-Codeflusses der Anbieterkonfiguration für „Über Apple anmelden“ ausgefüllt haben, wie im Abschnitt „Über Apple anmelden“ konfigurieren beschrieben.

  2. Da Firebase keine Nutzertokens speichert, wenn Nutzer mit „Über Apple anmelden“ erstellt werden, müssen Sie den Nutzer bitten, sich noch einmal anzumelden, bevor Sie sein Token widerrufen und das Konto löschen.

    Rufen Sie dann das Apple-OAuth-Zugriffstoken aus OAuthCredential ab und verwenden Sie es, um revokeAccessToken(auth, token) aufzurufen, um das Apple-OAuth-Zugriffstoken zu widerrufen.

    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.
          // ...
        });
    });
    
  3. Löschen Sie schließlich das Nutzerkonto und alle zugehörigen Daten.

Erweitert: Authentifizierung mit Firebase in Node.js

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

  1. Melden Sie den Nutzer mit seinem Apple-Konto an und rufen Sie das Apple-ID-Token des Nutzers ab. Dazu gibt es mehrere Möglichkeiten. Wenn Ihre Node.js-App beispielsweise ein Browser-Frontend hat, gehen Sie so vor:

    1. Generieren Sie im Backend eine zufällige Zeichenfolge (eine „Nonce“) und berechnen Sie ihren SHA256-Hash. Die Nonce ist ein Wert, der nur einmal verwendet wird, um eine einzelne Roundtrip-Kommunikation zwischen Ihrem Backend und den Authentifizierungsservern von Apple zu validieren.

      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');
    2. Geben Sie auf der Anmeldeseite die gehashte Nonce in der Konfiguration für „Über 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. Rufen Sie das Apple-ID-Token serverseitig aus der POST-Authentifizierungsantwort ab:

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

    Weitere Informationen finden Sie unter Webseite für „Über Apple anmelden“ konfigurieren.

  2. Nachdem Sie das Apple-ID-Token des Nutzers erhalten haben, erstellen Sie damit ein Anmeldedatenobjekt und melden Sie den Nutzer dann mit den Anmeldedaten an:

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

Nächste Schritte

Wenn sich ein Nutzer zum ersten Mal anmeldet, wird ein neues Nutzerkonto erstellt und mit den Anmeldedaten verknüpft, mit denen sich der Nutzer angemeldet hat (Nutzername und Passwort, Telefonnummer oder Informationen zum Authentifizierungsanbieter). Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Nutzer in allen Apps Ihres Projekts zu identifizieren, unabhängig davon, wie sich der Nutzer anmeldet.

  • In Ihren Apps ist es empfehlenswert, den Authentifizierungsstatus des Nutzers zu ermitteln, indem Sie einen Beobachter für das Objekt Auth festlegen. Anschließend können Sie die grundlegenden Profilinformationen des Nutzers aus dem Objekt User abrufen. Weitere Informationen finden Sie unter Nutzer verwalten.

  • In den Firebase Realtime Database und Cloud Storage Sicherheitsregeln können Sie die eindeutige Nutzer-ID des angemeldeten Nutzers aus der Variablen auth abrufen und damit steuern, auf welche Daten ein Nutzer zugreifen kann.

Sie können Nutzern die Anmeldung in Ihrer App mit mehreren Authentifizierungs anbietern ermöglichen, indem Sie die Anmeldedaten des Authentifizierungsanbieters mit einem bestehenden Nutzerkonto verknüpfen.

Rufen Sie signOut auf, um einen Nutzer abzumelden:

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