Autenticazione tramite Facebook Login con JavaScript

Puoi consentire agli utenti di autenticarsi con Firebase utilizzando i loro account Facebook integrando Facebook Login nella tua app. Puoi integrare Facebook Login utilizzando l'SDK Firebase per eseguire il flusso di accesso o eseguendo manualmente il flusso di accesso di Facebook e passando il token di accesso risultante a Firebase.

Prima di iniziare

  1. Aggiungi Firebase al tuo progetto JavaScript.
  2. Sul sito Facebook for Developers, recupera l'ID app e un App Secret per la tua app.
  3. Abilita accesso Facebook:
    1. Nella console Firebase, apri la sezione Autorizzazione.
    2. Nella scheda Metodo di accesso, attiva il metodo di accesso Facebook e specifica l'ID app e l'App Secret che hai ricevuto da Facebook.
    3. Poi, assicurati che l'URI di reindirizzamento OAuth (ad es. my-app-12345.firebaseapp.com/__/auth/handler) sia elencato come uno degli URI di reindirizzamento OAuth nella pagina delle impostazioni dell'app Facebook sul sito Facebook per gli sviluppatori nella configurazione di Impostazioni prodotto > Accesso Facebook.

Gestire il flusso di accesso con l'SDK Firebase

Se stai creando un'app web, il modo più semplice per autenticare gli utenti con Firebase utilizzando i loro account Facebook è gestire il flusso di accesso con l'SDK Firebase JavaScript. Se vuoi autenticare un utente in Node.js o in un altro ambiente non browser, devi gestire manualmente il flusso di accesso.

Per gestire il flusso di accesso con l'SDK Firebase JavaScript, segui questi passaggi: passaggi:

  1. Crea un'istanza dell'oggetto provider Facebook:
    WebWeb
    import { FacebookAuthProvider } from "firebase/auth";
    
    const provider = new FacebookAuthProvider();
    var provider = new firebase.auth.FacebookAuthProvider();
  2. Facoltativo: specifica gli ambiti OAuth 2.0 aggiuntivi che vuoi richiedere al provider di autenticazione. Per aggiungere un ambito, chiama addScope. Ad esempio:
    WebWeb
    provider.addScope('user_birthday');
    provider.addScope('user_birthday');
    Consulta il provider di autenticazione documentazione.
  3. (Facoltativo) Per localizzare il flusso OAuth del provider nelle preferenze dell'utente senza trasmettere esplicitamente i parametri OAuth personalizzati pertinenti, aggiornala sull'istanza Auth prima di avviare il flusso OAuth. Ad esempio:
    WebWeb
    import { getAuth } from "firebase/auth";
    
    const auth = getAuth();
    auth.languageCode = 'it';
    // To apply the default browser preference instead of explicitly setting it.
    // auth.useDeviceLanguage();
    firebase.auth().languageCode = 'it';
    // To apply the default browser preference instead of explicitly setting it.
    // firebase.auth().useDeviceLanguage();
  4. Facoltativo: specifica i parametri aggiuntivi del provider OAuth personalizzati da inviare con la richiesta OAuth. Per aggiungere un parametro personalizzato, chiama setCustomParameters sul provider inizializzato con un oggetto contenente la chiave come specificato dalla documentazione del provider OAuth e il valore corrispondente. Ad esempio:
    WebWeb
    provider.setCustomParameters({
      'display': 'popup'
    });
    provider.setCustomParameters({
      'display': 'popup'
    });
    I parametri OAuth obbligatori riservati non sono consentiti e verranno ignorati. Consulta riferimento del provider di autenticazione per ulteriori dettagli.
  5. Esegui l'autenticazione con Firebase utilizzando l'oggetto provider di Facebook. Puoi invitare gli utenti ad accedere con i loro account Facebook aprendo una finestra popup o reindirizzandoli alla pagina di accesso. Il metodo di reindirizzamento è preferito sui dispositivi mobili.
    • Per accedere con una finestra popup, chiama signInWithPopup:
      WebWeb
      import { getAuth, signInWithPopup, FacebookAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      signInWithPopup(auth, provider)
        .then((result) => {
          // The signed-in user info.
          const user = result.user;
      
          // This gives you a Facebook Access Token. You can use it to access the Facebook API.
          const credential = FacebookAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
      
          // 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 AuthCredential type that was used.
          const credential = FacebookAuthProvider.credentialFromError(error);
      
          // ...
        });
      firebase
        .auth()
        .signInWithPopup(provider)
        .then((result) => {
          /** @type {firebase.auth.OAuthCredential} */
          var credential = result.credential;
      
          // The signed-in user info.
          var user = result.user;
          // IdP data available in result.additionalUserInfo.profile.
            // ...
      
          // This gives you a Facebook Access Token. You can use it to access the Facebook API.
          var accessToken = credential.accessToken;
      
          // ...
        })
        .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;
      
          // ...
        });
      Nota inoltre che puoi recuperare il token OAuth del provider di Facebook, che può essere utilizzato per recuperare dati aggiuntivi utilizzando le API di Facebook.

      Qui puoi anche individuare e gestire gli errori. Per un elenco dei codici di errore, consulta la documentazione di riferimento per le autorizzazioni.

    • Per accedere reindirizzando alla pagina di accesso, chiama signInWithRedirect: Segui le best practice quando utilizzi "signInWithRedirect".
      WebWeb
      import { getAuth, signInWithRedirect } from "firebase/auth";
      
      const auth = getAuth();
      signInWithRedirect(auth, provider);
      firebase.auth().signInWithRedirect(provider);
      Puoi anche recuperare il token OAuth del provider Facebook chiamando getRedirectResult al caricamento della pagina:
      WebWeb
      import { getAuth, getRedirectResult, FacebookAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      getRedirectResult(auth)
        .then((result) => {
          // This gives you a Facebook Access Token. You can use it to access the Facebook API.
          const credential = FacebookAuthProvider.credentialFromResult(result);
          const token = credential.accessToken;
      
          const user = result.user;
          // 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;
          // AuthCredential type that was used.
          const credential = FacebookAuthProvider.credentialFromError(error);
          // ...
        });
      firebase.auth()
        .getRedirectResult()
        .then((result) => {
          if (result.credential) {
            /** @type {firebase.auth.OAuthCredential} */
            var credential = result.credential;
      
            // This gives you a Facebook Access Token. You can use it to access the Facebook API.
            var token = credential.accessToken;
            // ...
          }
          // The signed-in user info.
          var user = result.user;
          // 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;
          // ...
        });
      Qui puoi anche rilevare e gestire gli errori. Per un elenco dei codici di errore, consulta la documentazione di riferimento per le autorizzazioni.

Se hai attivato l'impostazione Un account per indirizzo email nella console Firebase, Quando un utente tenta di accedere a un provider (come Facebook) con un indirizzo email che ha già esiste per un altro provider utente Firebase (come Google), l'errore auth/account-exists-with-different-credential viene generato insieme a Oggetto AuthCredential (token di accesso di Facebook). Per completare l'accesso al fornitore scelto, l'utente deve prima accedere al fornitore esistente (Google) e poi eseguire il collegamento al precedente AuthCredential (token di accesso di Facebook).

Se utilizzi signInWithPopup, puoi gestire gli errori auth/account-exists-with-different-credential con un codice come nell'esempio seguente:

import {
  getAuth,
  linkWithCredential,
  signInWithPopup,
  FacebookAuthProvider,
} from "firebase/auth";

try {
  // Step 1: User tries to sign in using Facebook.
  let result = await signInWithPopup(getAuth(), new FacebookAuthProvider());
} catch (error) {
  // Step 2: User's email already exists.
  if (error.code === "auth/account-exists-with-different-credential") {
    // The pending Facebook credential.
    let pendingCred = error.credential;

    // Step 3: Save the pending credential in temporary storage,

    // Step 4: Let the user know that they already have an account
    // but with a different provider, and let them choose another
    // sign-in method.
  }
}

// ...

try {
  // Step 5: Sign the user in using their chosen method.
  let result = await signInWithPopup(getAuth(), userSelectedProvider);

  // Step 6: Link to the Facebook credential.
  // TODO: implement `retrievePendingCred` for your app.
  let pendingCred = retrievePendingCred();

  if (pendingCred !== null) {
    // As you have access to the pending credential, you can directly call the
    // link method.
    let user = await linkWithCredential(result.user, pendingCred);
  }

  // Step 7: Continue to app.
} catch (error) {
  // ...
}

Modalità di reindirizzamento

Questo errore viene gestito in modo simile nella modalità di reindirizzamento, con la differenza che il valore la credenziale deve essere memorizzata nella cache tra reindirizzamenti di pagina (ad esempio, usando la memoria di sessione).

Puoi anche autenticarti con Firebase utilizzando un account Facebook gestendo il flusso di accesso con l'SDK JavaScript di accesso a Facebook:

  1. Integra Facebook Login nella tua app seguendo le per gli sviluppatori. Assicurati di configurare l'accesso con Facebook con il tuo ID app Facebook:
    <script src="//connect.facebook.net/en_US/sdk.js"></script>
    <script>
      FB.init({
        /**********************************************************************
         * TODO(Developer): Change the value below with your Facebook app ID. *
         **********************************************************************/
        appId: '<YOUR_FACEBOOK_APP_ID>',
        status: true,
        xfbml: true,
        version: 'v2.6',
      });
    </script>
  2. Configuriamo anche un listener sullo stato di autenticazione di Facebook:
    FB.Event.subscribe('auth.authResponseChange', checkLoginState);
  3. Dopo aver integrato l'accesso con Facebook, aggiungi un pulsante di accesso con Facebook alle tue pagine web:
    <fb:login-button
      data-auto-logout-link="true"
      scope="public_profile,email"
      size="large"
    ></fb:login-button>
  4. Nel callback dello stato di autenticazione di Facebook, scambia il token di autenticazione della risposta di autorizzazione di Facebook con una credenziale Firebase e accedi a Firebase:
    WebWeb
    import { getAuth, onAuthStateChanged, signInWithCredential, signOut, FacebookAuthProvider } from "firebase/auth";
    const auth = getAuth();
    
    function checkLoginState(response) {
      if (response.authResponse) {
        // User is signed-in Facebook.
        const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
          unsubscribe();
          // Check if we are already signed-in Firebase with the correct user.
          if (!isUserEqual(response.authResponse, firebaseUser)) {
            // Build Firebase credential with the Facebook auth token.
            const credential = FacebookAuthProvider.credential(
                response.authResponse.accessToken);
    
            // Sign in with the credential from the Facebook user.
            signInWithCredential(auth, credential)
              .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 AuthCredential type that was used.
                const credential = FacebookAuthProvider.credentialFromError(error);
                // ...
              });
          } else {
            // User is already signed-in Firebase with the correct user.
          }
        });
      } else {
        // User is signed-out of Facebook.
        signOut(auth);
      }
    }
    function checkLoginState(response) {
      if (response.authResponse) {
        // User is signed-in Facebook.
        var unsubscribe = firebase.auth().onAuthStateChanged((firebaseUser) => {
          unsubscribe();
          // Check if we are already signed-in Firebase with the correct user.
          if (!isUserEqual(response.authResponse, firebaseUser)) {
            // Build Firebase credential with the Facebook auth token.
            var credential = firebase.auth.FacebookAuthProvider.credential(
                response.authResponse.accessToken);
    
            // Sign in with the credential from the Facebook user.
            firebase.auth().signInWithCredential(credential)
              .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;
                // ...
              });
          } else {
            // User is already signed-in Firebase with the correct user.
          }
        });
      } else {
        // User is signed-out of Facebook.
        firebase.auth().signOut();
      }
    }
    Qui puoi anche rilevare e gestire gli errori. Per un elenco dei codici di errore, consulta la documentazione di riferimento per l'autenticazione.
  5. Inoltre, devi verificare che l'utente di Facebook non abbia già eseguito l'accesso a Firebase per evitare una nuova autenticazione non necessaria:
    WebWeb
    import { FacebookAuthProvider } from "firebase/auth";
    
    function isUserEqual(facebookAuthResponse, firebaseUser) {
      if (firebaseUser) {
        const providerData = firebaseUser.providerData;
        for (let i = 0; i < providerData.length; i++) {
          if (providerData[i].providerId === FacebookAuthProvider.PROVIDER_ID &&
              providerData[i].uid === facebookAuthResponse.userID) {
            // We don't need to re-auth the Firebase connection.
            return true;
          }
        }
      }
      return false;
    }
    function isUserEqual(facebookAuthResponse, firebaseUser) {
      if (firebaseUser) {
        var providerData = firebaseUser.providerData;
        for (var i = 0; i < providerData.length; i++) {
          if (providerData[i].providerId === firebase.auth.FacebookAuthProvider.PROVIDER_ID &&
              providerData[i].uid === facebookAuthResponse.userID) {
            // We don't need to re-auth the Firebase connection.
            return true;
          }
        }
      }
      return false;
    }

Per eseguire l'autenticazione con Firebase in un'applicazione Node.js:

  1. Accedi all'utente con il suo account Facebook e recupera la sua pagina Facebook token di accesso. Ad esempio, fai accedere l'utente in un browser come descritto nella sezione Gestire manualmente il flusso di accesso, ma invia il token di accesso alla tua applicazione Node.js anziché utilizzarlo nell'app client.
  2. Dopo aver ottenuto il token di accesso di Facebook dell'utente, utilizzalo per creare un oggetto Credential e poi fai accedere l'utente con le credenziali:
    WebWeb
    import { getAuth, signInWithCredential, FacebookAuthProvider } from "firebase/auth";
    
    // Sign in with the credential from the Facebook user.
    const auth = getAuth();
    signInWithCredential(auth, credential)
      .then((result) => {
        // Signed in 
        const credential = FacebookAuthProvider.credentialFromResult(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 AuthCredential type that was used.
        const credential = FacebookAuthProvider.credentialFromError(error);
        // ...
      });
    // Sign in with the credential from the Facebook user.
    firebase.auth().signInWithCredential(credential)
      .then((result) => {
        // Signed in       
        var credential = result.credential;
        // ...
      })
      .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;
        // ...
      });

Eseguire l'autenticazione con Firebase in un'estensione di Chrome

Se stai sviluppando un'app di estensione di Chrome, consulta la Guida ai documenti fuori schermo.

Al momento della creazione del progetto, Firebase eseguirà il provisioning di un sottodominio univoco per il tuo progetto: https://my-app-12345.firebaseapp.com.

Verrà utilizzato anche come meccanismo di reindirizzamento per l'accesso OAuth. Quel dominio dovrebbe essere consentito per tutti i provider OAuth supportati. Tuttavia, gli utenti potrebbero notare che dominio durante l'accesso a Facebook prima di reindirizzare all'applicazione: Continua su: https://my-app-12345.firebaseapp.com.

Per evitare di visualizzare il sottodominio, puoi configurare un dominio personalizzato con Firebase Hosting:

  1. Segui i passaggi da 1 a 3 in Configura il dominio per Hosting. Quando esegui la verifica la proprietà del dominio, Hosting esegue il provisioning di un certificato SSL per il tuo dominio personalizzato.
  2. Aggiungi il tuo dominio personalizzato all'elenco dei domini autorizzati nella Console Firebase: auth.custom.domain.com.
  3. Nella Developer Console di Facebook o nella pagina di configurazione di OAuth, autorizza l'URL della pagina di reindirizzamento. che saranno accessibili sul tuo dominio personalizzato: https://auth.custom.domain.com/__/auth/handler.
  4. Quando inizili la libreria JavaScript, specifica il tuo dominio personalizzato con il campo authDomain:
    var config = {
      apiKey: '...',
      // Changed from 'PROJECT_ID.firebaseapp.com'.
      authDomain: 'auth.custom.domain.com',
      databaseURL: 'https://PROJECT_ID.firebaseio.com',
      projectId: 'PROJECT_ID',
      storageBucket: 'PROJECT_ID.firebasestorage.app',
      messagingSenderId: 'SENDER_ID'
    };
    firebase.initializeApp(config);

Passaggi successivi

Dopo che un utente ha eseguito l'accesso per la prima volta, viene creato un nuovo account utente e collegato alle credenziali, ovvero nome utente e password, numero di telefono o informazioni del fornitore di autenticazione, con cui l'utente ha eseguito l'accesso. Questo nuovo viene archiviato come parte del progetto Firebase e può essere utilizzato per identificare a un utente in ogni app del progetto, a prescindere da come esegue l'accesso.

  • Nelle tue app, il modo consigliato per conoscere lo stato di autenticazione dell'utente è impostare un osservatore sull'oggetto Auth. Puoi quindi ottenere l'input dell'utente informazioni di base del profilo dall'oggetto User. Vedi Gestire gli utenti.

  • In Firebase Realtime Database e Cloud Storage Regole di sicurezza, puoi ottieni l'ID utente unico dell'utente che ha eseguito l'accesso dalla variabile auth e usarli per controllare i dati a cui un utente può accedere.

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

Per scollegare un utente, chiama signOut:

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

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