Autenticarsi utilizzando Apple con JavaScript

Puoi consentire ai tuoi utenti di autenticarsi con Firebase utilizzando il proprio ID Apple utilizzando l'SDK Firebase per eseguire il flusso di accesso OAuth 2.0 end-to-end.

Prima di iniziare

Per accedere agli utenti che utilizzano Apple, configura innanzitutto Accedi con Apple sul sito degli sviluppatori Apple, quindi abilita Apple come provider di accesso per il tuo progetto Firebase.

Unisciti al programma per sviluppatori Apple

L'accesso con Apple può essere configurato solo dai membri dell'Apple Developer Program .

Configura l'accesso con Apple

Nel sito Apple Developer , procedi come segue:

  1. Associa il tuo sito web alla tua app come descritto nella prima sezione di Configura l'accesso con Apple per il web . Quando richiesto, registra il seguente URL come URL di ritorno:

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

    Puoi ottenere l'ID progetto Firebase nella pagina delle impostazioni della console Firebase .

    Una volta terminato, prendi nota del tuo nuovo ID servizio, che ti servirà nella sezione successiva.

  2. Crea un accesso con la chiave privata Apple . Avrai bisogno della tua nuova chiave privata e dell'ID chiave nella sezione successiva.
  3. Se utilizzi una delle funzionalità di Firebase Authentication che inviano e-mail agli utenti, incluso l'accesso tramite collegamento e-mail, la verifica dell'indirizzo e-mail, la revoca della modifica dell'account e altro, configura il servizio di inoltro e-mail privato Apple e registrati noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (o il dominio del tuo modello di email personalizzato) in modo che Apple possa inoltrare le email inviate tramite Firebase Authentication a indirizzi email Apple anonimizzati.

Abilita Apple come provider di accesso

  1. Aggiungi Firebase al tuo progetto .
  2. Nella console Firebase , apri la sezione Autenticazione . Nella scheda Metodo di accesso , abilita il provider Apple . Specifica l'ID servizio creato nella sezione precedente. Inoltre, nella sezione Configurazione del flusso di codice OAuth , specifica il tuo ID team Apple, la chiave privata e l'ID chiave che hai creato nella sezione precedente.

Rispettare i requisiti relativi ai dati anonimi di Apple

Accedi con Apple offre agli utenti la possibilità di rendere anonimi i propri dati, incluso il proprio indirizzo e-mail, al momento dell'accesso. Gli utenti che scelgono questa opzione hanno indirizzi e-mail con il dominio privaterelay.appleid.com . Quando utilizzi Accedi con Apple nella tua app, devi rispettare tutte le politiche o i termini per sviluppatori applicabili di Apple relativi a questi ID Apple anonimizzati.

Ciò include l'ottenimento del consenso dell'utente richiesto prima di associare qualsiasi informazione personale direttamente identificativa a un ID Apple anonimo. Quando si utilizza l'autenticazione Firebase, ciò può includere le seguenti azioni:

  • Collega un indirizzo email a un ID Apple anonimo o viceversa.
  • Collega un numero di telefono a un ID Apple anonimo o viceversa
  • Collega una credenziale social non anonima (Facebook, Google, ecc.) a un ID Apple anonimo o viceversa.

L'elenco sopra riportato non è esaustivo. Fai riferimento al contratto di licenza del programma per sviluppatori Apple nella sezione Iscrizione del tuo account sviluppatore per assicurarti che la tua app soddisfi i requisiti Apple.

Gestisci il flusso di accesso con l'SDK Firebase

Se stai creando un'app Web, il modo più semplice per autenticare i tuoi utenti con Firebase utilizzando i loro account Apple è gestire l'intero flusso di accesso con Firebase JavaScript SDK.

Per gestire il flusso di accesso con l'SDK JavaScript di Firebase, procedi nel seguente modo:

  1. Crea un'istanza di OAuthProvider utilizzando l'ID provider corrispondente apple.com .

    Web modular API

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

    Web namespaced API

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. Facoltativo: specificare ulteriori ambiti OAuth 2.0 oltre a quello predefinito che si desidera richiedere al provider di autenticazione.

    Web modular API

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

    Web namespaced API

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

    Per impostazione predefinita, quando è abilitato Un account per indirizzo e-mail , Firebase richiede ambiti e-mail e nomi. Se modifichi questa impostazione su Più account per indirizzo email , Firebase non richiede alcun ambito ad Apple a meno che tu non lo specifichi.

  3. Facoltativo: se desideri visualizzare la schermata di accesso di Apple in una lingua diversa dall'inglese, imposta il parametro locale . Consulta la documentazione Accedi con Apple per le lingue supportate.

    Web modular API

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

    Web namespaced API

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. Autenticarsi con Firebase utilizzando l'oggetto provider OAuth. Puoi chiedere ai tuoi utenti di accedere con i loro account Apple aprendo una finestra pop-up o reindirizzando alla pagina di accesso. Il metodo di reindirizzamento è preferito sui dispositivi mobili.

    • Per accedere con una finestra pop-up, chiama signInWithPopup() :

      Web modular API

      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 namespaced API

      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;
      
          // ...
        });
    • Per accedere reindirizzando alla pagina di accesso, chiama signInWithRedirect() :

    Seguire le procedure consigliate quando si utilizza signInWithRedirect , linkWithRedirect o reauthenticateWithRedirect .

    Web modular API

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

    Web namespaced API

    firebase.auth().signInWithRedirect(provider);

    Dopo che l'utente ha completato l'accesso ed è tornato alla pagina, puoi ottenere il risultato dell'accesso chiamando getRedirectResult() :

    Web modular API

    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 namespaced API

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

    Qui è anche possibile rilevare e gestire gli errori. Per un elenco dei codici di errore, consulta il riferimento API .

    A differenza di altri provider supportati da Firebase Auth, Apple non fornisce l'URL di una foto.

    Inoltre, quando l'utente sceglie di non condividere la propria email con l'app, Apple fornisce a quell'utente un indirizzo email univoco (nel formato xyz@privaterelay.appleid.com ), che condivide con la tua app. Se hai configurato il servizio di inoltro e-mail privato, Apple inoltra le e-mail inviate all'indirizzo anonimo al vero indirizzo e-mail dell'utente.

    Apple condivide le informazioni dell'utente come il nome visualizzato con le app solo la prima volta che un utente accede. Di solito, Firebase memorizza il nome visualizzato la prima volta che un utente accede con Apple, che puoi ottenere con firebase.auth().currentUser.displayName . Tuttavia, se in precedenza hai utilizzato Apple per far accedere un utente all'app senza utilizzare Firebase, Apple non fornirà a Firebase il nome visualizzato dell'utente.

Riautenticazione e collegamento dell'account

Lo stesso modello può essere utilizzato con reauthenticateWithPopup() e reauthenticateWithRedirect() , che puoi utilizzare per recuperare una nuova credenziale per operazioni sensibili che richiedono un accesso recente:

Web modular API

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 namespaced API

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;

    // ...
  });

Inoltre, puoi utilizzare linkWithPopup() e linkWithRedirect() per collegare diversi provider di identità agli account esistenti.

Tieni presente che Apple richiede che tu ottenga il consenso esplicito degli utenti prima di collegare i loro account Apple ad altri dati.

Ad esempio, per collegare un account Facebook all'account Firebase corrente, utilizza il token di accesso ottenuto dall'accesso dell'utente a Facebook:

Web modular API

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 namespaced API

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

Autenticati con Firebase in un'estensione di Chrome

Se stai creando un'app di estensione per Chrome, consulta la guida Offscreen Documents .

Tieni presente che devi comunque verificare il dominio personalizzato con Apple in modo simile al dominio firebaseapp.com predefinito:

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

Revoca del token

Apple richiede che le app che supportano la creazione di account consentano agli utenti di avviare l'eliminazione del proprio account all'interno dell'app, come descritto nelle Linee guida per la revisione dell'App Store

Per soddisfare questo requisito, implementare i seguenti passaggi:

  1. Assicurati di aver compilato la sezione di configurazione dell'ID servizi e del flusso di codice OAuth della configurazione del provider Accedi con Apple, come indicato nella sezione Configura l'accesso con Apple .

  2. Poiché Firebase non memorizza i token utente quando gli utenti vengono creati con Accedi con Apple, devi chiedere all'utente di accedere nuovamente prima di revocare il token ed eliminare l'account.

    Quindi, ottieni il token di accesso Apple OAuth da OAuthCredential e utilizzalo per chiamare revokeAccessToken(auth, token) per revocare il token di accesso Apple OAuth.

    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. Infine, elimina l'account utente (e tutti i dati associati).

Avanzato: autenticazione con Firebase in Node.js

Per autenticarsi con Firebase in un'applicazione Node.js:

  1. Accedi all'utente con il suo account Apple e ottieni il token ID Apple dell'utente. Puoi ottenere questo risultato in diversi modi. Ad esempio, se la tua app Node.js ha un front-end del browser:

    1. Sul tuo backend, genera una stringa casuale (un "nonce") e calcola il suo hash SHA256. Il nonce è un valore monouso che utilizzi per convalidare un singolo viaggio di andata e ritorno tra il tuo backend e i server di autenticazione di Apple.

      Web modular API

      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 namespaced API

      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. Nella pagina di accesso, specifica il nonce con hash nella configurazione Accedi con 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. Ottieni il token ID Apple dal lato server della risposta di autenticazione POST:

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

    Consulta anche Configurazione della pagina Web per l'accesso con Apple .

  2. Dopo aver ottenuto il token ID Apple dell'utente, utilizzalo per creare un oggetto Credential e quindi accedere all'utente con la credenziale:

    Web modular API

    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 namespaced API

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

Prossimi passi

Dopo che un utente accede per la prima volta, viene creato un nuovo account utente e collegato alle credenziali, ovvero nome utente e password, numero di telefono o informazioni sul provider di autenticazione, con cui l'utente ha effettuato l'accesso. Questo nuovo account viene archiviato come parte del tuo progetto Firebase e può essere utilizzato per identificare un utente in ogni app del tuo progetto, indipendentemente dalla modalità di accesso dell'utente.

  • Nelle tue app, il modo consigliato per conoscere lo stato di autenticazione del tuo utente è impostare un osservatore sull'oggetto Auth . È quindi possibile ottenere le informazioni di base del profilo dell'utente dall'oggetto User . Vedi Gestisci utenti .

  • Nel tuo Firebase Realtime Database e Cloud Storage Security Rules , puoi ottenere l'ID utente univoco dell'utente che ha effettuato l'accesso dalla variabile auth e utilizzarlo per controllare a quali dati può accedere un utente.

Puoi consentire agli utenti di accedere alla tua app utilizzando più provider di autenticazione collegando le credenziali del provider di autenticazione a un account utente esistente.

Per disconnettere un utente, chiamare signOut :

Web modular API

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

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

Web namespaced API

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

Puoi consentire ai tuoi utenti di autenticarsi con Firebase utilizzando il proprio ID Apple utilizzando l'SDK Firebase per eseguire il flusso di accesso OAuth 2.0 end-to-end.

Prima di iniziare

Per accedere agli utenti che utilizzano Apple, configura innanzitutto Accedi con Apple sul sito degli sviluppatori Apple, quindi abilita Apple come provider di accesso per il tuo progetto Firebase.

Unisciti al programma per sviluppatori Apple

L'accesso con Apple può essere configurato solo dai membri dell'Apple Developer Program .

Configura l'accesso con Apple

Nel sito Apple Developer , procedi come segue:

  1. Associa il tuo sito web alla tua app come descritto nella prima sezione di Configura l'accesso con Apple per il web . Quando richiesto, registra il seguente URL come URL di ritorno:

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

    Puoi ottenere l'ID progetto Firebase nella pagina delle impostazioni della console Firebase .

    Una volta terminato, prendi nota del tuo nuovo ID servizio, che ti servirà nella sezione successiva.

  2. Crea un accesso con la chiave privata Apple . Avrai bisogno della tua nuova chiave privata e dell'ID chiave nella sezione successiva.
  3. Se utilizzi una delle funzionalità di Firebase Authentication che inviano e-mail agli utenti, incluso l'accesso tramite collegamento e-mail, la verifica dell'indirizzo e-mail, la revoca della modifica dell'account e altro, configura il servizio di inoltro e-mail privato Apple e registrati noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (o il dominio del tuo modello di email personalizzato) in modo che Apple possa inoltrare le email inviate tramite Firebase Authentication a indirizzi email Apple anonimizzati.

Abilita Apple come provider di accesso

  1. Aggiungi Firebase al tuo progetto .
  2. Nella console Firebase , apri la sezione Autenticazione . Nella scheda Metodo di accesso , abilita il provider Apple . Specifica l'ID servizio creato nella sezione precedente. Inoltre, nella sezione Configurazione del flusso di codice OAuth , specifica il tuo ID team Apple, la chiave privata e l'ID chiave che hai creato nella sezione precedente.

Rispettare i requisiti relativi ai dati anonimizzati di Apple

Accedi con Apple offre agli utenti la possibilità di rendere anonimi i propri dati, incluso il proprio indirizzo e-mail, al momento dell'accesso. Gli utenti che scelgono questa opzione hanno indirizzi e-mail con il dominio privaterelay.appleid.com . Quando utilizzi Accedi con Apple nella tua app, devi rispettare tutte le politiche o i termini per sviluppatori applicabili di Apple relativi a questi ID Apple anonimizzati.

Ciò include l'ottenimento del consenso dell'utente richiesto prima di associare qualsiasi informazione personale che possa identificare direttamente un ID Apple anonimo. Quando si utilizza l'autenticazione Firebase, ciò può includere le seguenti azioni:

  • Collega un indirizzo email a un ID Apple anonimo o viceversa.
  • Collega un numero di telefono a un ID Apple anonimo o viceversa
  • Collega una credenziale social non anonima (Facebook, Google, ecc.) a un ID Apple anonimo o viceversa.

L'elenco sopra riportato non è esaustivo. Fai riferimento al contratto di licenza del programma per sviluppatori Apple nella sezione Iscrizione del tuo account sviluppatore per assicurarti che la tua app soddisfi i requisiti Apple.

Gestisci il flusso di accesso con l'SDK Firebase

Se stai creando un'app Web, il modo più semplice per autenticare i tuoi utenti con Firebase utilizzando i loro account Apple è gestire l'intero flusso di accesso con Firebase JavaScript SDK.

Per gestire il flusso di accesso con l'SDK JavaScript di Firebase, procedi nel seguente modo:

  1. Crea un'istanza di OAuthProvider utilizzando l'ID provider corrispondente apple.com .

    Web modular API

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

    Web namespaced API

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. Facoltativo: specificare ulteriori ambiti OAuth 2.0 oltre a quello predefinito che si desidera richiedere al provider di autenticazione.

    Web modular API

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

    Web namespaced API

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

    Per impostazione predefinita, quando è abilitato Un account per indirizzo e-mail , Firebase richiede ambiti e-mail e nomi. Se modifichi questa impostazione su Più account per indirizzo email , Firebase non richiede alcun ambito ad Apple a meno che tu non lo specifichi.

  3. Facoltativo: se desideri visualizzare la schermata di accesso di Apple in una lingua diversa dall'inglese, imposta il parametro locale . Consulta la documentazione Accedi con Apple per le lingue supportate.

    Web modular API

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

    Web namespaced API

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. Autenticarsi con Firebase utilizzando l'oggetto provider OAuth. Puoi chiedere ai tuoi utenti di accedere con i loro account Apple aprendo una finestra pop-up o reindirizzando alla pagina di accesso. Il metodo di reindirizzamento è preferito sui dispositivi mobili.

    • Per accedere con una finestra pop-up, chiama signInWithPopup() :

      Web modular API

      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 namespaced API

      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;
      
          // ...
        });
    • Per accedere reindirizzando alla pagina di accesso, chiama signInWithRedirect() :

    Seguire le procedure consigliate quando si utilizza signInWithRedirect , linkWithRedirect o reauthenticateWithRedirect .

    Web modular API

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

    Web namespaced API

    firebase.auth().signInWithRedirect(provider);

    Dopo che l'utente ha completato l'accesso ed è tornato alla pagina, puoi ottenere il risultato dell'accesso chiamando getRedirectResult() :

    Web modular API

    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 namespaced API

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

    Qui è anche possibile rilevare e gestire gli errori. Per un elenco dei codici di errore, consulta il riferimento API .

    A differenza di altri provider supportati da Firebase Auth, Apple non fornisce l'URL di una foto.

    Inoltre, quando l'utente sceglie di non condividere la propria email con l'app, Apple fornisce a quell'utente un indirizzo email univoco (nel formato xyz@privaterelay.appleid.com ), che condivide con la tua app. Se hai configurato il servizio di inoltro e-mail privato, Apple inoltra le e-mail inviate all'indirizzo anonimo al vero indirizzo e-mail dell'utente.

    Apple condivide le informazioni dell'utente come il nome visualizzato con le app solo la prima volta che un utente accede. Di solito, Firebase memorizza il nome visualizzato la prima volta che un utente accede con Apple, che puoi ottenere con firebase.auth().currentUser.displayName . Tuttavia, se in precedenza hai utilizzato Apple per far accedere un utente all'app senza utilizzare Firebase, Apple non fornirà a Firebase il nome visualizzato dell'utente.

Riautenticazione e collegamento dell'account

Lo stesso modello può essere utilizzato con reauthenticateWithPopup() e reauthenticateWithRedirect() , che puoi utilizzare per recuperare una nuova credenziale per operazioni sensibili che richiedono un accesso recente:

Web modular API

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 namespaced API

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;

    // ...
  });

Inoltre, puoi utilizzare linkWithPopup() e linkWithRedirect() per collegare diversi provider di identità agli account esistenti.

Tieni presente che Apple richiede che tu ottenga il consenso esplicito degli utenti prima di collegare i loro account Apple ad altri dati.

Ad esempio, per collegare un account Facebook all'account Firebase corrente, utilizza il token di accesso ottenuto dall'accesso dell'utente a Facebook:

Web modular API

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 namespaced API

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

Autenticati con Firebase in un'estensione di Chrome

Se stai creando un'app di estensione per Chrome, consulta la guida Offscreen Documents .

Tieni presente che devi comunque verificare il dominio personalizzato con Apple in modo simile al dominio firebaseapp.com predefinito:

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

Revoca del token

Apple richiede che le app che supportano la creazione di account consentano agli utenti di avviare l'eliminazione del proprio account all'interno dell'app, come descritto nelle Linee guida per la revisione dell'App Store

Per soddisfare questo requisito, implementare i seguenti passaggi:

  1. Assicurati di aver compilato la sezione di configurazione dell'ID servizi e del flusso di codice OAuth della configurazione del provider Accedi con Apple, come indicato nella sezione Configura l'accesso con Apple .

  2. Poiché Firebase non memorizza i token utente quando gli utenti vengono creati con Accedi con Apple, devi chiedere all'utente di accedere nuovamente prima di revocare il token ed eliminare l'account.

    Quindi, ottieni il token di accesso Apple OAuth da OAuthCredential e utilizzalo per chiamare revokeAccessToken(auth, token) per revocare il token di accesso Apple OAuth.

    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. Infine, elimina l'account utente (e tutti i dati associati).

Avanzato: autenticazione con Firebase in Node.js

Per autenticarsi con Firebase in un'applicazione Node.js:

  1. Accedi all'utente con il suo account Apple e ottieni il token ID Apple dell'utente. Puoi ottenere questo risultato in diversi modi. Ad esempio, se la tua app Node.js ha un front-end del browser:

    1. Sul tuo backend, genera una stringa casuale (un "nonce") e calcola il suo hash SHA256. Il nonce è un valore monouso che utilizzi per convalidare un singolo viaggio di andata e ritorno tra il tuo backend e i server di autenticazione di Apple.

      Web modular API

      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 namespaced API

      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. Nella pagina di accesso, specifica il nonce con hash nella configurazione Accedi con 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. Ottieni il token ID Apple dal lato server della risposta di autenticazione POST:

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

    Consulta anche Configurazione della pagina Web per l'accesso con Apple .

  2. Dopo aver ottenuto il token ID Apple dell'utente, utilizzalo per creare un oggetto Credential e quindi accedere all'utente con la credenziale:

    Web modular API

    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 namespaced API

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

Prossimi passi

Dopo che un utente accede per la prima volta, viene creato un nuovo account utente e collegato alle credenziali, ovvero nome utente e password, numero di telefono o informazioni sul provider di autenticazione, con cui l'utente ha effettuato l'accesso. Questo nuovo account viene archiviato come parte del tuo progetto Firebase e può essere utilizzato per identificare un utente in ogni app del tuo progetto, indipendentemente dalla modalità di accesso dell'utente.

  • Nelle tue app, il modo consigliato per conoscere lo stato di autenticazione del tuo utente è impostare un osservatore sull'oggetto Auth . È quindi possibile ottenere le informazioni di base del profilo dell'utente dall'oggetto User . Vedi Gestisci utenti .

  • Nel tuo Firebase Realtime Database e Cloud Storage Security Rules , puoi ottenere l'ID utente univoco dell'utente che ha effettuato l'accesso dalla variabile auth e utilizzarlo per controllare a quali dati può accedere un utente.

Puoi consentire agli utenti di accedere alla tua app utilizzando più provider di autenticazione collegando le credenziali del provider di autenticazione a un account utente esistente.

Per disconnettere un utente, chiamare signOut :

Web modular API

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

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

Web namespaced API

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