Autenticar usando Apple con JavaScript

Puede permitir que sus usuarios se autentiquen con Firebase usando su ID de Apple mediante el SDK de Firebase para llevar a cabo el flujo de inicio de sesión de OAuth 2.0 de un extremo a otro.

Antes de que empieces

Para iniciar sesión como usuario con Apple, primero configure Iniciar sesión con Apple en el sitio para desarrolladores de Apple y luego habilite Apple como proveedor de inicio de sesión para su proyecto de Firebase.

Únase al programa de desarrolladores de Apple

Iniciar sesión con Apple solo lo pueden configurar los miembros del Programa de desarrolladores de Apple .

Configurar Iniciar sesión con Apple

En el sitio para desarrolladores de Apple , haga lo siguiente:

  1. Asocie su sitio web con su aplicación como se describe en la primera sección de Configurar el inicio de sesión con Apple para la web . Cuando se le solicite, registre la siguiente URL como URL de retorno:

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

    Puede obtener el ID de su proyecto de Firebase en la página de configuración de la consola de Firebase .

    Cuando haya terminado, tome nota de su nuevo ID de servicio, que necesitará en la siguiente sección.

  2. Cree un inicio de sesión con la clave privada de Apple . Necesitará su nueva clave privada y su ID de clave en la siguiente sección.
  3. Si utiliza cualquiera de las funciones de Firebase Authentication que envían correos electrónicos a los usuarios, incluido el inicio de sesión mediante enlace de correo electrónico, la verificación de la dirección de correo electrónico, la revocación de cambio de cuenta y otras, configure el servicio de retransmisión de correo electrónico privado de Apple y regístrese noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (o su dominio de plantilla de correo electrónico personalizado) para que Apple pueda transmitir los correos electrónicos enviados mediante Firebase Authentication a direcciones de correo electrónico anónimas de Apple.

Habilite Apple como proveedor de inicio de sesión

  1. Agrega Firebase a tu proyecto .
  2. En Firebase console , abre la sección Auth . En la pestaña Método de inicio de sesión , habilite el proveedor de Apple . Especifique el ID de servicio que creó en la sección anterior. Además, en la sección de configuración del flujo de código OAuth , especifique su ID de equipo Apple y la clave privada y el ID de clave que creó en la sección anterior.

Cumplir con los requisitos de datos anonimizados de Apple

Iniciar sesión con Apple ofrece a los usuarios la opción de anonimizar sus datos, incluida su dirección de correo electrónico, al iniciar sesión. Los usuarios que eligen esta opción tienen direcciones de correo electrónico con el dominio privaterelay.appleid.com . Cuando utiliza Iniciar sesión con Apple en su aplicación, debe cumplir con las políticas o términos de desarrollador aplicables de Apple con respecto a estos ID de Apple anónimos.

Esto incluye obtener el consentimiento del usuario requerido antes de asociar cualquier información personal de identificación directa con una ID de Apple anónima. Cuando se utiliza la autenticación de Firebase, esto puede incluir las siguientes acciones:

  • Vincula una dirección de correo electrónico a una ID de Apple anónima o viceversa.
  • Vincular un número de teléfono a una ID de Apple anónima o viceversa
  • Vincula una credencial social no anónima (Facebook, Google, etc.) a una ID de Apple anónima o viceversa.

La lista de arriba no es exhaustiva. Consulte el Acuerdo de licencia del programa para desarrolladores de Apple en la sección Membresía de su cuenta de desarrollador para asegurarse de que su aplicación cumpla con los requisitos de Apple.

Maneja el flujo de inicio de sesión con el SDK de Firebase

Si está creando una aplicación web, la forma más sencilla de autenticar a sus usuarios con Firebase utilizando sus cuentas de Apple es manejar todo el flujo de inicio de sesión con el SDK de JavaScript de Firebase.

Para manejar el flujo de inicio de sesión con el SDK de JavaScript de Firebase, sigue estos pasos:

  1. Cree una instancia de OAuthProvider utilizando el ID de proveedor correspondiente 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. Opcional: Especifique ámbitos de OAuth 2.0 adicionales además del valor predeterminado que desea solicitar al proveedor de autenticación.

    Web modular API

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

    Web namespaced API

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

    De forma predeterminada, cuando se habilita Una cuenta por dirección de correo electrónico , Firebase solicita ámbitos de nombre y correo electrónico. Si cambia esta configuración a Varias cuentas por dirección de correo electrónico , Firebase no solicita ningún ámbito a Apple a menos que los especifique.

  3. Opcional: si desea mostrar la pantalla de inicio de sesión de Apple en un idioma que no sea inglés, configure el parámetro locale . Consulte los documentos Iniciar sesión con Apple para conocer las configuraciones regionales admitidas.

    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. Autentíquese con Firebase utilizando el objeto proveedor de OAuth. Puede solicitar a sus usuarios que inicien sesión con sus cuentas de Apple abriendo una ventana emergente o redirigiéndolos a la página de inicio de sesión. Se prefiere el método de redireccionamiento en dispositivos móviles.

    • Para iniciar sesión con una ventana emergente, llame 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;
      
          // ...
        });
    • Para iniciar sesión redirigiendo a la página de inicio de sesión, llame a signInWithRedirect() :

    Siga las mejores prácticas al utilizar 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);

    Después de que el usuario complete el inicio de sesión y regrese a la página, puede obtener el resultado del inicio de sesión llamando a 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;
    
        // ...
      });

    Aquí también es donde puedes detectar y manejar errores. Para obtener una lista de códigos de error, consulte la referencia de API .

    A diferencia de otros proveedores compatibles con Firebase Auth, Apple no proporciona una URL de foto.

    Además, cuando el usuario elige no compartir su correo electrónico con la aplicación, Apple proporciona una dirección de correo electrónico única para ese usuario (del formato xyz@privaterelay.appleid.com ), que comparte con su aplicación. Si configuró el servicio de retransmisión de correo electrónico privado, Apple reenvía los correos electrónicos enviados a la dirección anónima a la dirección de correo electrónico real del usuario.

    Apple solo comparte información del usuario, como el nombre para mostrar, con las aplicaciones la primera vez que un usuario inicia sesión. Por lo general, Firebase almacena el nombre para mostrar la primera vez que un usuario inicia sesión en Apple, que puede obtener con firebase.auth().currentUser.displayName . Sin embargo, si anteriormente usaste Apple para iniciar sesión como usuario en la aplicación sin usar Firebase, Apple no proporcionará a Firebase el nombre para mostrar del usuario.

Reautenticación y vinculación de cuentas

Se puede usar el mismo patrón con reauthenticateWithPopup() y reauthenticateWithRedirect() , que puede usar para recuperar una credencial nueva para operaciones confidenciales que requieren un inicio de sesión reciente:

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;

    // ...
  });

Y puede utilizar linkWithPopup() y linkWithRedirect() para vincular diferentes proveedores de identidad a cuentas existentes.

Tenga en cuenta que Apple requiere que obtenga el consentimiento explícito de los usuarios antes de vincular sus cuentas de Apple a otros datos.

Por ejemplo, para vincular una cuenta de Facebook a la cuenta actual de Firebase, use el token de acceso que obtuvo al iniciar sesión como usuario en 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.
    });

Autenticarse con Firebase en una extensión de Chrome

Si está creando una aplicación de extensión de Chrome, consulte la guía Documentos fuera de pantalla .

Tenga en cuenta que aún debe verificar el dominio personalizado con Apple de manera similar al dominio predeterminado firebaseapp.com:

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

Revocación de token

Apple exige que las aplicaciones que admiten la creación de cuentas permitan a los usuarios iniciar la eliminación de su cuenta dentro de la aplicación, como se describe en las Pautas de revisión de la App Store.

Para cumplir con este requisito, implemente los siguientes pasos:

  1. Asegúrese de completar la sección de configuración de flujo de código OAuth y ID de servicios de la configuración del proveedor Iniciar sesión con Apple, como se describe en la sección Configurar Iniciar sesión con Apple .

  2. Dado que Firebase no almacena tokens de usuario cuando los usuarios se crean con Iniciar sesión con Apple, debes pedirle al usuario que inicie sesión nuevamente antes de revocar su token y eliminar la cuenta.

    Luego, obtenga el token de acceso de Apple OAuth de OAuthCredential y utilícelo para llamar revokeAccessToken(auth, token) para revocar el token de acceso de 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. Finalmente, elimine la cuenta de usuario (y todos los datos asociados).

Avanzado: Autenticar con Firebase en Node.js

Para autenticarse con Firebase en una aplicación Node.js:

  1. Inicie sesión como usuario con su cuenta Apple y obtenga el token de ID de Apple del usuario. Puedes lograr esto de varias maneras. Por ejemplo, si su aplicación Node.js tiene una interfaz de navegador:

    1. En su backend, genere una cadena aleatoria (un "nonce") y calcule su hash SHA256. El nonce es un valor de uso único que se utiliza para validar un único viaje de ida y vuelta entre su backend y los servidores de autenticación de 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. En su página de inicio de sesión, especifique el nonce hash en su configuración de Iniciar sesión 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. Obtenga el token de ID de Apple del lado del servidor de respuesta de autenticación PUBLICADA:

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

    Consulte también Configuración de su página web para iniciar sesión con Apple .

  2. Después de obtener el token de ID de Apple del usuario, úselo para crear un objeto Credencial y luego inicie sesión como usuario con la credencial:

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

Próximos pasos

Después de que un usuario inicia sesión por primera vez, se crea una nueva cuenta de usuario y se vincula a las credenciales (es decir, el nombre de usuario y la contraseña, el número de teléfono o la información del proveedor de autenticación) con las que el usuario inició sesión. Esta nueva cuenta se almacena como parte de su proyecto de Firebase y se puede usar para identificar a un usuario en cada aplicación de su proyecto, independientemente de cómo inicie sesión el usuario.

  • En sus aplicaciones, la forma recomendada de conocer el estado de autenticación de su usuario es configurar un observador en el objeto Auth . Luego puede obtener la información básica del perfil del usuario desde el objeto User . Consulte Administrar usuarios .

  • En las reglas de seguridad de Firebase Realtime Database y Cloud Storage, puede obtener el ID de usuario único del usuario que inició sesión a partir de la variable auth y usarlo para controlar a qué datos puede acceder un usuario.

Puede permitir que los usuarios inicien sesión en su aplicación utilizando múltiples proveedores de autenticación vinculando las credenciales del proveedor de autenticación a una cuenta de usuario existente.

Para cerrar la sesión de un usuario, llame 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.
});
,

Puede permitir que sus usuarios se autentiquen con Firebase usando su ID de Apple mediante el SDK de Firebase para llevar a cabo el flujo de inicio de sesión de OAuth 2.0 de un extremo a otro.

Antes de que empieces

Para iniciar sesión como usuario con Apple, primero configure Iniciar sesión con Apple en el sitio para desarrolladores de Apple y luego habilite Apple como proveedor de inicio de sesión para su proyecto de Firebase.

Únase al programa de desarrolladores de Apple

Iniciar sesión con Apple solo lo pueden configurar los miembros del Programa de desarrolladores de Apple .

Configurar Iniciar sesión con Apple

En el sitio para desarrolladores de Apple , haga lo siguiente:

  1. Asocie su sitio web con su aplicación como se describe en la primera sección de Configurar el inicio de sesión con Apple para la web . Cuando se le solicite, registre la siguiente URL como URL de retorno:

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

    Puede obtener el ID de su proyecto de Firebase en la página de configuración de la consola de Firebase .

    Cuando haya terminado, tome nota de su nuevo ID de servicio, que necesitará en la siguiente sección.

  2. Cree un inicio de sesión con la clave privada de Apple . Necesitará su nueva clave privada y su ID de clave en la siguiente sección.
  3. Si utiliza cualquiera de las funciones de Firebase Authentication que envían correos electrónicos a los usuarios, incluido el inicio de sesión mediante enlace de correo electrónico, la verificación de la dirección de correo electrónico, la revocación de cambio de cuenta y otras, configure el servicio de retransmisión de correo electrónico privado de Apple y regístrese noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (o su dominio de plantilla de correo electrónico personalizado) para que Apple pueda transmitir los correos electrónicos enviados mediante Firebase Authentication a direcciones de correo electrónico anónimas de Apple.

Habilite Apple como proveedor de inicio de sesión

  1. Agrega Firebase a tu proyecto .
  2. En Firebase console , abre la sección Auth . En la pestaña Método de inicio de sesión , habilite el proveedor de Apple . Especifique el ID de servicio que creó en la sección anterior. Además, en la sección de configuración del flujo de código OAuth , especifique su ID de equipo Apple y la clave privada y el ID de clave que creó en la sección anterior.

Cumplir con los requisitos de datos anonimizados de Apple

Iniciar sesión con Apple ofrece a los usuarios la opción de anonimizar sus datos, incluida su dirección de correo electrónico, al iniciar sesión. Los usuarios que eligen esta opción tienen direcciones de correo electrónico con el dominio privaterelay.appleid.com . Cuando utiliza Iniciar sesión con Apple en su aplicación, debe cumplir con las políticas o términos de desarrollador aplicables de Apple con respecto a estos ID de Apple anónimos.

Esto incluye obtener el consentimiento del usuario requerido antes de asociar cualquier información personal de identificación directa con una ID de Apple anónima. Cuando se utiliza la autenticación de Firebase, esto puede incluir las siguientes acciones:

  • Vincula una dirección de correo electrónico a una ID de Apple anónima o viceversa.
  • Vincular un número de teléfono a una ID de Apple anónima o viceversa
  • Vincula una credencial social no anónima (Facebook, Google, etc.) a una ID de Apple anónima o viceversa.

La lista de arriba no es exhaustiva. Consulte el Acuerdo de licencia del programa para desarrolladores de Apple en la sección Membresía de su cuenta de desarrollador para asegurarse de que su aplicación cumpla con los requisitos de Apple.

Maneja el flujo de inicio de sesión con el SDK de Firebase

Si está creando una aplicación web, la forma más sencilla de autenticar a sus usuarios con Firebase utilizando sus cuentas de Apple es manejar todo el flujo de inicio de sesión con el SDK de JavaScript de Firebase.

Para manejar el flujo de inicio de sesión con el SDK de JavaScript de Firebase, sigue estos pasos:

  1. Cree una instancia de OAuthProvider utilizando el ID de proveedor correspondiente 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. Opcional: Especifique ámbitos de OAuth 2.0 adicionales además del valor predeterminado que desea solicitar al proveedor de autenticación.

    Web modular API

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

    Web namespaced API

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

    De forma predeterminada, cuando se habilita Una cuenta por dirección de correo electrónico , Firebase solicita ámbitos de nombre y correo electrónico. Si cambia esta configuración a Varias cuentas por dirección de correo electrónico , Firebase no solicita ningún ámbito a Apple a menos que los especifique.

  3. Opcional: si desea mostrar la pantalla de inicio de sesión de Apple en un idioma que no sea inglés, configure el parámetro locale . Consulte los documentos Iniciar sesión con Apple para conocer las configuraciones regionales admitidas.

    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. Autentíquese con Firebase utilizando el objeto proveedor de OAuth. Puede solicitar a sus usuarios que inicien sesión con sus cuentas de Apple abriendo una ventana emergente o redirigiéndolos a la página de inicio de sesión. Se prefiere el método de redireccionamiento en dispositivos móviles.

    • Para iniciar sesión con una ventana emergente, llame 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;
      
          // ...
        });
    • Para iniciar sesión redirigiendo a la página de inicio de sesión, llame a signInWithRedirect() :

    Siga las mejores prácticas al utilizar 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);

    Después de que el usuario complete el inicio de sesión y regrese a la página, puede obtener el resultado del inicio de sesión llamando a 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;
    
        // ...
      });

    Aquí también es donde puedes detectar y manejar errores. Para obtener una lista de códigos de error, consulte la referencia de API .

    A diferencia de otros proveedores compatibles con Firebase Auth, Apple no proporciona una URL de foto.

    Además, cuando el usuario elige no compartir su correo electrónico con la aplicación, Apple proporciona una dirección de correo electrónico única para ese usuario (del formato xyz@privaterelay.appleid.com ), que comparte con su aplicación. Si configuró el servicio de retransmisión de correo electrónico privado, Apple reenvía los correos electrónicos enviados a la dirección anónima a la dirección de correo electrónico real del usuario.

    Apple solo comparte información del usuario, como el nombre para mostrar, con las aplicaciones la primera vez que un usuario inicia sesión. Por lo general, Firebase almacena el nombre para mostrar la primera vez que un usuario inicia sesión en Apple, que puede obtener con firebase.auth().currentUser.displayName . Sin embargo, si anteriormente usaste Apple para iniciar sesión como usuario en la aplicación sin usar Firebase, Apple no proporcionará a Firebase el nombre para mostrar del usuario.

Reautenticación y vinculación de cuentas

Se puede usar el mismo patrón con reauthenticateWithPopup() y reauthenticateWithRedirect() , que puede usar para recuperar una credencial nueva para operaciones confidenciales que requieren un inicio de sesión reciente:

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;

    // ...
  });

Y puede utilizar linkWithPopup() y linkWithRedirect() para vincular diferentes proveedores de identidad a cuentas existentes.

Tenga en cuenta que Apple requiere que obtenga el consentimiento explícito de los usuarios antes de vincular sus cuentas de Apple a otros datos.

Por ejemplo, para vincular una cuenta de Facebook a la cuenta actual de Firebase, use el token de acceso que obtuvo al iniciar sesión en 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.
    });

Autenticarse con Firebase en una extensión de Chrome

Si está creando una aplicación de extensión de Chrome, consulte la guía Documentos fuera de pantalla .

Tenga en cuenta que aún debe verificar el dominio personalizado con Apple de manera similar al dominio predeterminado firebaseapp.com:

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

Revocación de token

Apple exige que las aplicaciones que admiten la creación de cuentas permitan a los usuarios iniciar la eliminación de su cuenta dentro de la aplicación, como se describe en las Pautas de revisión de la App Store.

Para cumplir con este requisito, implemente los siguientes pasos:

  1. Asegúrese de completar la sección de configuración de flujo de código OAuth y ID de servicios de la configuración del proveedor Iniciar sesión con Apple, como se describe en la sección Configurar Iniciar sesión con Apple .

  2. Dado que Firebase no almacena tokens de usuario cuando los usuarios se crean con Iniciar sesión con Apple, debes pedirle al usuario que inicie sesión nuevamente antes de revocar su token y eliminar la cuenta.

    Luego, obtenga el token de acceso de Apple OAuth de OAuthCredential y utilícelo para llamar revokeAccessToken(auth, token) para revocar el token de acceso de 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. Finalmente, elimine la cuenta de usuario (y todos los datos asociados).

Avanzado: Autenticar con Firebase en Node.js

Para autenticarse con Firebase en una aplicación Node.js:

  1. Inicie sesión como usuario con su cuenta Apple y obtenga el token de ID de Apple del usuario. Puedes lograr esto de varias maneras. Por ejemplo, si su aplicación Node.js tiene una interfaz de navegador:

    1. En su backend, genere una cadena aleatoria (un "nonce") y calcule su hash SHA256. El nonce es un valor de uso único que se utiliza para validar un único viaje de ida y vuelta entre su backend y los servidores de autenticación de 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. En su página de inicio de sesión, especifique el nonce hash en su configuración de Iniciar sesión 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. Obtenga el token de ID de Apple del lado del servidor de respuesta de autenticación PUBLICADA:

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

    Consulte también Configuración de su página web para iniciar sesión con Apple .

  2. Después de obtener el token de ID de Apple del usuario, úselo para crear un objeto Credencial y luego inicie sesión como usuario con la credencial:

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

Próximos pasos

Después de que un usuario inicia sesión por primera vez, se crea una nueva cuenta de usuario y se vincula a las credenciales (es decir, el nombre de usuario y la contraseña, el número de teléfono o la información del proveedor de autenticación) con las que el usuario inició sesión. Esta nueva cuenta se almacena como parte de su proyecto de Firebase y se puede usar para identificar a un usuario en cada aplicación de su proyecto, independientemente de cómo inicie sesión el usuario.

  • En sus aplicaciones, la forma recomendada de conocer el estado de autenticación de su usuario es configurar un observador en el objeto Auth . Luego puede obtener la información básica del perfil del usuario desde el objeto User . Consulte Administrar usuarios .

  • En las reglas de seguridad de Firebase Realtime Database y Cloud Storage, puede obtener el ID de usuario único del usuario que inició sesión a partir de la variable auth y usarlo para controlar a qué datos puede acceder un usuario.

Puede permitir que los usuarios inicien sesión en su aplicación utilizando múltiples proveedores de autenticación vinculando las credenciales del proveedor de autenticación a una cuenta de usuario existente.

Para cerrar la sesión de un usuario, llame 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.
});