Mit JavaScript über Apple authentifizieren

Sie können Ihre Nutzer mit ihrer Apple-ID bei Firebase authentifizieren, indem Sie den OAuth 2.0-Anmeldevorgang mit dem Firebase SDK abwickeln.

Hinweis

Wenn Sie Nutzer über Apple anmelden möchten, müssen Sie zuerst die Anmeldung über Apple auf der Entwicklerwebsite von Apple konfigurieren und dann Apple als Anmeldeanbieter für Ihr Firebase-Projekt aktivieren.

Am Apple-Entwicklerprogramm teilnehmen

„Über Apple anmelden“ kann nur von Mitgliedern des Apple-Entwicklerprogramms konfiguriert werden.

„Über Apple anmelden“ konfigurieren

Führen Sie auf der Website Apple Developer die folgenden Schritte aus:

  1. Verknüpfen Sie Ihre Website mit Ihrer App wie im ersten Abschnitt des Hilfeartikels Mit Apple im Web anmelden beschrieben. Registrieren Sie auf Aufforderung die folgende URL als Return-URL:

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

    Sie finden die Firebase-Projekt-ID auf der Seite Firebase Console-Einstellungen.

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

  2. Erstellen Sie einen privaten Schlüssel für „Mit Apple anmelden“. Sie benötigen Ihren neuen privaten Schlüssel und die Schlüssel-ID im nächsten Abschnitt.
  3. Wenn Sie eine der Funktionen von Firebase Authentication verwenden, über die E-Mails an Nutzer gesendet werden, z. B. die Anmeldung über einen E-Mail-Link, die Bestätigung der E-Mail-Adresse oder die Widerrufung von Kontoänderungen, konfigurieren Sie den privaten E-Mail-Relay-Dienst von Apple und registrieren Sie noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com (oder die Domain Ihrer benutzerdefinierten E-Mail-Vorlage), damit Apple von Firebase Authentication gesendete E-Mails an anonymisierte E-Mail-Adressen von Apple weiterleiten kann.

Apple als Anmeldeanbieter aktivieren

  1. Fügen Sie Ihrem Projekt Firebase hinzu.
  2. Öffnen Sie in der Firebase Console den Bereich Auth. Aktivieren Sie auf dem Tab Anmeldemethode den Anbieter Apple. Geben Sie die Dienst-ID an, die Sie im vorherigen Abschnitt erstellt haben. Geben Sie außerdem im Abschnitt OAuth-Code-Ablauf konfigurieren 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 für anonymisierte Daten einhalten

Mit „Über Apple anmelden“ haben Nutzer die Möglichkeit, ihre Daten, einschließlich ihrer E-Mail-Adresse, bei der Anmeldung zu 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.

Außerdem muss die Einwilligung des Nutzers eingeholt werden, bevor personenbezogene Daten mit einer anonymisierten Apple-ID verknüpft werden. Bei der Verwendung der Firebase-Authentifizierung kann dies Folgendes umfassen:

  • E-Mail-Adresse mit einer anonymisierten Apple-ID verknüpfen und umgekehrt
  • Telefonnummer mit einer anonymisierten Apple-ID verknüpfen und umgekehrt
  • Nicht-anonyme Anmeldedaten für soziale Medien (z. B. Facebook oder Google) mit einer anonymisierten Apple-ID verknüpfen und umgekehrt

Die Liste oben ist unvollständig. Lesen Sie die Lizenzvereinbarung des Apple-Entwicklerprogramms im Bereich „Mitgliedschaft“ Ihres Entwicklerkontos, um sicherzustellen, dass Ihre App die Anforderungen von Apple erfüllt.

Anmeldevorgang mit dem Firebase SDK abwickeln

Wenn Sie eine Webanwendung entwickeln, ist die einfachste Möglichkeit, Ihre Nutzer mit ihren Apple-Konten bei Firebase 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 eines 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 Sie zusätzlich zum Standardbereich 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 Berechtigungen 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 lassen möchten, legen Sie den Parameter locale fest. Eine Liste der unterstützten Sprachen finden Sie in den Dokumenten 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. Authentifizierung mit Firebase über das OAuth-Anbieterobjekt Sie können Nutzer auffordern, sich mit ihren Apple-Konten anzumelden, indem Sie entweder ein Pop-up-Fenster öffnen oder zur Anmeldeseite weiterleiten. Die Weiterleitungsmethode wird auf Mobilgeräten bevorzugt.

    • Wenn Sie sich über ein Pop-up-Fenster anmelden möchten, drücken Sie 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;
      
          // ...
        });
    • Rufen Sie signInWithRedirect() auf, um sich anzumelden und zur Anmeldeseite weitergeleitet zu werden:

    Beachten Sie die Best Practices, wenn Sie signInWithRedirect, linkWithRedirect oder reauthenticateWithRedirect verwenden.

    Web

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

    Web

    firebase.auth().signInWithRedirect(provider);

    Nachdem der Nutzer die Anmeldung abgeschlossen und zur Seite zurückgekehrt ist, können Sie das Anmeldeergebnis durch Aufrufen von 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 behandeln. Eine Liste der Fehlercodes findest du in der API-Referenz.

    Anders als andere von Firebase Auth unterstützte Anbieter stellt Apple keine Foto-URL bereit.

    Wenn der Nutzer seine E-Mail-Adresse nicht mit der App teilen möchte, stellt Apple eine eindeutige E-Mail-Adresse für diesen Nutzer bereit (im Format xyz@privaterelay.appleid.com), die an Ihre App weitergegeben wird. Wenn Sie den privaten E-Mail-Relay-Dienst konfiguriert haben, leitet Apple alle an die anonymisierte Adresse gesendeten E-Mails an die reale E-Mail-Adresse des Nutzers weiter.

    Apple gibt Nutzerinformationen wie den Anzeigenamen nur dann an Apps weiter, wenn sich ein Nutzer zum ersten Mal anmeldet. Normalerweise wird der Anzeigename in Firebase gespeichert, wenn sich ein Nutzer zum ersten Mal mit Apple anmeldet. Sie können ihn mit firebase.auth().currentUser.displayName abrufen. Wenn Sie einen Nutzer jedoch zuvor über Apple in der App angemeldet haben, ohne Firebase zu verwenden, stellt Apple Firebase keinen Anzeigenamen des Nutzers zur Verfügung.

Neue Authentifizierung und Kontoverknüpfung

Dasselbe Muster kann mit reauthenticateWithPopup() und reauthenticateWithRedirect() verwendet werden, um für vertrauliche Vorgänge, die eine aktuelle Anmeldung erfordern, neue Anmeldedaten abzurufen:

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() kannst du verschiedene Identitätsanbieter mit vorhandenen Konten verknüpfen.

Apple verlangt, 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 bei der 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.
    });

In einer Chrome-Erweiterung mit Firebase authentifizieren

Wenn Sie eine Chrome-Erweiterung entwickeln, lesen Sie den Leitfaden zu Offscreen-Dokumenten.

Die benutzerdefinierte Domain muss jedoch wie die Standarddomain „firebaseapp.com“ bei Apple bestätigt werden:

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

Widerruf von Tokens

Apple verlangt, dass Nutzer in Apps, in denen ein Konto erstellt werden kann, die Löschung ihres Kontos innerhalb der App initiieren können, wie in den App Store-Richtlinien für die Überprüfung beschrieben.

Führen Sie dazu die folgenden Schritte aus:

  1. Achten Sie darauf, dass Sie in der Anbieterkonfiguration für die Anmeldung über Apple die Abschnitte Services-ID und OAuth-Codeflusskonfiguration ausgefüllt haben, wie im Abschnitt Anmeldung über Apple 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.

    Rufe dann das Apple OAuth-Zugriffstoken aus der OAuthCredential ab und verwende es, um revokeAccessToken(auth, token) aufzurufen und 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 abschließend das Nutzerkonto und alle zugehörigen Daten.

Fortgeschrittene Nutzer: Mit Firebase in Node.js authentifizieren

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

  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-Anwendung beispielsweise ein Browser-Frontend hat:

    1. Generieren Sie in Ihrem Backend einen zufälligen String (einen „Nonce“) und berechnen Sie den SHA256-Hash. Der Nonce ist ein Einmalwert, mit dem eine einzelne Verbindung zwischen Ihrem Backend und den Authentifizierungsservern von Apple validiert wird.

      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 Ihrer Anmeldeseite den gehashten Nonce in der Konfiguration für die Anmeldung über Apple 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. Rufe das Apple-ID-Token serverseitig aus der geposteten 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 die Anmeldung über Apple konfigurieren.

  2. Nachdem du das Apple-ID-Token des Nutzers abgerufen hast, verwende es, um ein Anmeldedatenobjekt zu erstellen und den Nutzer dann mit den Anmeldedaten anzumelden:

    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

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

  • In Ihren Apps sollten Sie den Authentifizierungsstatus des Nutzers am besten über einen Beobachter für das Auth-Objekt ermitteln. Die grundlegenden Profilinformationen des Nutzers können Sie dann aus dem User-Objekt abrufen. Weitere Informationen finden Sie unter Nutzer verwalten.

  • In Ihren 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 erlauben, sich über mehrere Authentifizierungsanbieter in Ihrer App anzumelden, indem Sie Anmeldedaten des Authentifizierungsanbieters mit einem vorhandenen Nutzerkonto verknüpfen.

Wenn Sie einen Nutzer abmelden möchten, rufen Sie signOut auf:

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