Autentica mediante OpenID Connect en apps web

Si actualizaste a Firebase Authentication con Identity Platform, puedes autenticar tus usuarios con Firebase mediante el proveedor que admita OpenID Connect (OIDC) de tu preferencia, lo que permite usar proveedores de identidad que no son compatibles de forma nativa con Firebase.

Antes de comenzar

Para que los usuarios accedan con un proveedor de OIDC, primero debes recopilar cierta información del proveedor:

  • ID de cliente: Es una string única para el proveedor que identifica tu app. Es posible que el proveedor te asigne un ID de cliente diferente para cada plataforma que admitas. Este es uno de los valores de la reclamación aud en los tokens de ID emitidos por tu proveedor.

  • Secreto de cliente: Es una string secreta que usa el proveedor para confirmar la propiedad de un ID de cliente. Para cada ID de cliente, necesitarás un secreto de cliente que coincida. Este valor solo es necesario si usas el flujo de código de autenticación, lo que es muy recomendable.

  • Emisor: Es una string que identifica a tu proveedor. Debe ser una URL que, cuando se agrega con /.well-known/openid-configuration, es la ubicación del documento de descubrimiento de OIDC del proveedor. Por ejemplo, si el emisor es https://auth.example.com, el documento de descubrimiento debe estar disponible en https://auth.example.com/.well-known/openid-configuration.

Una vez que tengas la información anterior, habilita OpenID Connect como proveedor de acceso para el proyecto de Firebase.

  1. Agrega Firebase al proyecto de JavaScript.

  2. Actualiza a Firebase Authentication con Identity Platform si aún no lo has hecho. La autenticación de OpenID Connect solo está disponible en proyectos actualizados.

  3. En la página Proveedores de acceso de Firebase console, haz clic en Agregar proveedor nuevo y, luego, en OpenID Connect.

  4. Selecciona si usarás el flujo de código de autorización o el flujo de concesión implícito.

    Debes usar siempre el flujo de código si tu proveedor lo admite. El flujo implícito es menos seguro y no se recomienda su uso.

  5. Asígnale un nombre a este proveedor. Toma nota del ID de proveedor que se genera (algo como oidc.example-provider). Lo necesitarás cuando agregues el código de acceso a tu app.

  6. Especifica tu ID de cliente, el secreto de cliente y la string de emisor de tu proveedor. Estos valores deben coincidir exactamente con los valores que te asignó el proveedor.

  7. Guarda los cambios.

Maneja el flujo de acceso con el SDK de Firebase

La manera más sencilla de autenticar a los usuarios con Firebase mediante tu proveedor de OIDC es manejar todo el flujo de acceso con el SDK de Firebase.

Para manejar el flujo de acceso con el SDK de Firebase JavaScript, sigue estos pasos:

  1. Crea una instancia de un OAuthProvider con el ID de proveedor que obtuviste en Firebase console.

    API modular web

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('oidc.example-provider');
    

    API con espacio de nombres web

    var provider = new firebase.auth.OAuthProvider('oidc.example-provider');
    
  2. Opcional: Especifica parámetros de OAuth personalizados adicionales que quieras enviar con la solicitud de OAuth.

    API modular web

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    API con espacio de nombres web

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    Consulta con tu proveedor los parámetros que admite. Ten en cuenta que no puedes pasar los parámetros obligatorios de Firebase con setCustomParameters. Estos parámetros son client_id, response_type, redirect_uri, state, scope y response_mode.

  3. Opcional: Especifica permisos de OAuth 2.0 adicionales aparte del perfil básico que quieres solicitar al proveedor de autenticación.

    API modular web

    provider.addScope('mail.read');
    provider.addScope('calendars.read');
    

    API con espacio de nombres web

    provider.addScope('mail.read');
    provider.addScope('calendars.read');
    

    Consulta con tu proveedor los permisos que admite.

  4. Autentica con Firebase usando el objeto del proveedor de OAuth.

    Puedes redireccionar al usuario a la página de acceso del proveedor o abrir la página de acceso en una ventana emergente del navegador.

    Flujo de redireccionamiento

    Para redireccionar a la página de acceso del proveedor, llama a signInWithRedirect():

    API modular web

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

    API con espacio de nombres web

    firebase.auth().signInWithRedirect(provider);
    

    Después de que el usuario termine de acceder y vuelva a tu app, puedes obtener el resultado de acceso con solo llamar a getRedirectResult().

    API modular web

    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    API con espacio de nombres web

    firebase.auth().getRedirectResult()
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    Flujo de ventana emergente

    API modular web

    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        // IdP data available using getAdditionalUserInfo(result)
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    API con espacio de nombres web

    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    
  5. Si bien los ejemplos anteriores se enfocan en los flujos de acceso, puedes usar el mismo patrón para vincular un proveedor de OIDC con un usuario existente mediante linkWithRedirect() y linkWithPopup(), y volver a autenticar a un usuario con reauthenticateWithRedirect() y reauthenticateWithPopup(), que se pueden usar para recuperar credenciales nuevas para operaciones sensibles que requieren un acceso reciente.

Maneja el flujo de acceso de manera manual

Si ya implementaste el flujo de acceso de OpenID Connect en tu app, puedes usar el token de ID directamente para realizar la autenticación con Firebase:

API modular web

import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth";

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
signInWithCredential(getAuth(), credential)
    .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.

        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
    })
    .catch((error) => {
        // Handle error.
    });

API con espacio de nombres web

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
firebase.auth().signInWithCredential(credential)
    .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.

        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
    })
    .catch((error) => {
        // Handle error.
    });