Para usar identidades externas con Identity-Aware Proxy (IAP), tu aplicación necesita una página de inicio de sesión. IAP redirigirá a los usuarios a esta página para que se autentiquen antes de poder acceder a recursos seguros.
En este artículo se explica cómo crear una página de autenticación con FirebaseUI, una biblioteca de JavaScript de código abierto. FirebaseUI proporciona elementos personalizables que ayudan a reducir el código repetitivo y gestiona los flujos para que los usuarios inicien sesión con una amplia gama de proveedores de identidades.
Para empezar más rápido, deja que IAP aloje la interfaz de usuario por ti. De esta forma, puedes probar las identidades externas sin escribir código adicional. Para casos más avanzados, también puedes crear tu propia página de inicio de sesión desde cero. Esta opción es más compleja, pero te permite controlar por completo el flujo de autenticación y la experiencia de usuario.
Antes de empezar
Habilita las identidades externas y selecciona la opción Proporcionaré mi propia interfaz de usuario durante la configuración.
Instalar las bibliotecas
Instala las bibliotecas gcip-iap
, firebase
y firebaseui
. El módulo gcip-iap
abstrae las comunicaciones entre tu aplicación, las compras en la aplicación y Identity Platform. Las bibliotecas firebase
y firebaseui
proporcionan los componentes básicos de la interfaz de autenticación.
npm install firebase --save
npm install firebaseui --save
npm install gcip-iap --save
Ten en cuenta que el módulo gcip-iap
no está disponible mediante CDN.
Después, puedes import
los módulos de tus archivos de origen. Usa las importaciones correctas para tu versión del SDK:
gcip-iap v0.1.4 o versiones anteriores
// Import firebase modules.
import * as firebase from "firebase/app";
import "firebase/auth";
// Import firebaseui module.
import * as firebaseui from 'firebaseui'
// Import gcip-iap module.
import * as ciap from 'gcip-iap';
gcip-iap v1.0.0 o versiones posteriores
A partir de la versión v1.0.0, gcip-iap
requiere la dependencia de elemento del mismo nivel firebase
v9 o una versión posterior.
Si vas a migrar a la versión 1.0.0 de gcip-iap
o a una posterior, completa las siguientes acciones:
- Actualiza las versiones de
firebase
yfirebaseui
en tu archivopackage.json
a v9.6.0+ y v6.0.0+, respectivamente. - Actualiza las instrucciones de importación de
firebase
de la siguiente manera:
// Import firebase modules.
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
// Import firebaseui module.
import * as firebaseui from 'firebaseui'
// Import gcip-iap module.
No es necesario realizar cambios adicionales en el código.
Para ver otras opciones de instalación, como usar versiones localizadas de las bibliotecas, consulta las instrucciones en GitHub.
Configurar tu aplicación
FirebaseUI usa un objeto de configuración que especifica los arrendatarios y los proveedores que se van a usar para la autenticación. Una configuración completa puede ser muy larga y tener un aspecto similar a este:
// The project configuration.
const configs = {
// Configuration for project identified by API key API_KEY1.
API_KEY1: {
authDomain: 'project-id1.firebaseapp.com',
// Decide whether to ask user for identifier to figure out
// what tenant to select or whether to present all the tenants to select from.
displayMode: 'optionFirst', // Or identifierFirst
// The terms of service URL and privacy policy URL for the page
// where the user select tenant or enter email for tenant/provider
// matching.
tosUrl: 'http://localhost/tos',
privacyPolicyUrl: 'http://localhost/privacypolicy',
callbacks: {
// The callback to trigger when the selection tenant page
// or enter email for tenant matching page is shown.
selectTenantUiShown: () => {
// Show title and additional display info.
},
// The callback to trigger when the sign-in page
// is shown.
signInUiShown: (tenantId) => {
// Show tenant title and additional display info.
},
beforeSignInSuccess: (user) => {
// Do additional processing on user before sign-in is
// complete.
return Promise.resolve(user);
}
},
tenants: {
// Tenant configuration for tenant ID tenantId1.
tenantId1: {
// Full label, display name, button color and icon URL of the
// tenant selection button. Only needed if you are
// using the option first option.
fullLabel: 'ACME Portal',
displayName: 'ACME',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
// Sign-in providers enabled for tenantId1.
signInOptions: [
// Microsoft sign-in.
{
provider: 'microsoft.com',
providerName: 'Microsoft',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
loginHintKey: 'login_hint'
},
// Email/password sign-in.
{
provider: 'password',
// Do not require display name on sign up.
requireDisplayName: false,
disableSignUp: {
// Disable user from signing up with email providers.
status: true,
adminEmail: 'admin@example.com',
helpLink: 'https://www.example.com/trouble_signing_in'
}
},
// SAML provider. (multiple SAML providers can be passed)
{
provider: 'saml.my-provider1',
providerName: 'SAML provider',
fullLabel: 'Employee Login',
buttonColor: '#4666FF',
iconUrl: 'https://www.example.com/photos/my_idp/saml.png'
},
],
// If there is only one sign-in provider eligible for the user,
// whether to show the provider selection page.
immediateFederatedRedirect: true,
signInFlow: 'redirect', // Or popup
// The terms of service URL and privacy policy URL for the sign-in page
// specific to each tenant.
tosUrl: 'http://localhost/tenant1/tos',
privacyPolicyUrl: 'http://localhost/tenant1/privacypolicy'
},
// Tenant configuration for tenant ID tenantId2.
tenantId2: {
fullLabel: 'OCP Portal',
displayName: 'OCP',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
// Tenant2 supports a SAML, OIDC and Email/password sign-in.
signInOptions: [
// Email/password sign-in.
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
// Do not require display name on sign up.
requireDisplayName: false
},
// SAML provider. (multiple SAML providers can be passed)
{
provider: 'saml.my-provider2',
providerName: 'SAML provider',
fullLabel: 'Contractor Portal',
buttonColor: '#4666FF',
iconUrl: 'https://www.example.com/photos/my_idp/saml.png'
},
// OIDC provider. (multiple OIDC providers can be passed)
{
provider: 'oidc.my-provider1',
providerName: 'OIDC provider',
buttonColor: '#4666FF',
iconUrl: 'https://www.example.com/photos/my_idp/oidc.png'
},
],
},
// Tenant configuration for tenant ID tenantId3.
tenantId3: {
fullLabel: 'Tenant3 Portal',
displayName: 'Tenant3',
buttonColor: '#007bff',
iconUrl: '<icon-url-of-sign-in-button>',
// Tenant3 supports a Google and Email/password sign-in.
signInOptions: [
// Email/password sign-in.
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
// Do not require display name on sign up.
requireDisplayName: false
},
// Google provider.
{
provider: 'google.com',
scopes: ['scope1', 'scope2', 'https://example.com/scope3'],
loginHintKey: 'login_hint',
customParameters: {
prompt: 'consent',
},
},
],
// Sets the adminRestrictedOperation configuration for providers
// including federated, email/password, email link and phone number.
adminRestrictedOperation: {
status: true,
adminEmail: 'admin@example.com',
helpLink: 'https://www.example.com/trouble_signing_in'
}
},
},
},
};
En las secciones siguientes se explica cómo configurar algunos de los campos específicos de las compras en la aplicación. Para ver ejemplos de cómo definir otros campos, consulta el fragmento de código anterior o la documentación de FirebaseUI en GitHub.
Definir la clave de API
Una configuración típica empieza con una clave de API para tu proyecto:
// The project configuration.
const configs = {
// Configuration for API_KEY.
API_KEY: {
// Config goes here
}
}
En la mayoría de los casos, solo tiene que especificar una clave de API. Sin embargo, si quieres usar una sola URL de autenticación en varios proyectos, puedes incluir varias claves de API:
const configs = {
API_KEY1: {
// Config goes here
},
API_KEY2: {
// Config goes here
},
}
Obtener el dominio de autenticación
Asigna al campo authdomain
el dominio aprovisionado para facilitar el inicio de sesión federado. Puedes obtener este campo en la página Identity Platform de la Google Cloud consola.
Especificar IDs de clientes
Una configuración requiere una lista de inquilinos y proveedores con los que los usuarios pueden autenticarse.
Cada inquilino se identifica por su ID. Si usas la autenticación a nivel de proyecto (sin inquilinos), utiliza el identificador especial _
como clave de API. Por ejemplo:
const configs = {
// Configuration for project identified by API key API_KEY1.
API_KEY1: {
tenants: {
// Project-level IdPs flow.
_: {
// Tenant config goes here
},
// Single tenant flow.
1036546636501: {
// Tenant config goes here
}
}
}
}
También puedes especificar una configuración de arrendatario con comodín mediante el operador *
.
Este arrendatario se usa como alternativa si no se encuentra ningún ID coincidente.
Configurar proveedores de clientes
Cada propietario tiene sus propios proveedores, que se especifican en el campo signInOptions
:
tenantId1: {
signInOptions: [
// Options go here
]
}
Consulta Configurar proveedores de inicio de sesión en la documentación de FirebaseUI para saber cómo configurar proveedores.
Además de los pasos descritos en la documentación de FirebaseUI, hay varios campos específicos de las compras en la aplicación que dependen del modo de selección de inquilino que elijas. Consulta la siguiente sección para obtener más información sobre estos campos.
Elegir un modo de selección de clientes
Los usuarios pueden seleccionar un arrendatario de dos formas: modo de opciones primero o modo de identificador primero.
En el modo de opciones, el usuario empieza seleccionando un arrendatario de una lista y, a continuación, introduce su nombre de usuario y contraseña. En el modo de identificador, el usuario introduce primero su correo electrónico. A continuación, el sistema selecciona automáticamente el primer inquilino con un proveedor de identidades que coincida con el dominio del correo.
Para usar el modo Opciones, selecciona displayMode
como optionFirst
. A continuación, deberá proporcionar información de configuración para el botón de cada inquilino, como displayName
, buttonColor
y iconUrl
. También se puede proporcionar un fullLabel
opcional para anular toda la etiqueta del botón en lugar de solo el nombre visible.
A continuación, se muestra un ejemplo de un arrendatario configurado para usar el modo de opciones:
tenantId1: {
fullLabel: 'ACME Portal',
displayName: 'ACME',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
// ...
Para usar el modo de identificador, cada opción de inicio de sesión debe especificar un campo hd
que indique qué dominio admite. Puede ser una expresión regular (como /@example\.com$/
) o la cadena de dominio (por ejemplo, example.com
).
El código de abajo muestra un arrendatario configurado para usar el modo de identificador:
tenantId1: {
signInOptions: [
// Email/password sign-in.
{
hd: 'acme.com', // using regex: /@acme\.com$/
// ...
},
Habilitar la redirección inmediata
Si tu aplicación solo admite un proveedor de identidades, al definir immediateFederatedRedirect
como true
, se omitirá la interfaz de usuario de inicio de sesión y se redirigirá al usuario directamente al proveedor.
Configurar retrollamadas
El objeto de configuración contiene un conjunto de retrollamadas que se invocan en varios puntos durante el flujo de autenticación. Esto te permite personalizar aún más la interfaz de usuario. Están disponibles los siguientes ganchos:
selectTenantUiShown() |
Se activa cuando se muestra la interfaz de usuario para seleccionar un arrendatario. Úsalo si quieres modificar la interfaz de usuario con un título o un tema personalizados. |
signInUiShown(tenantId) |
Se activa cuando se selecciona un arrendatario y se muestra la interfaz de usuario para que el usuario introduzca sus credenciales. Úsalo si quieres modificar la interfaz de usuario con un título o un tema personalizados. |
beforeSignInSuccess(user) |
Se activa antes de que se complete el inicio de sesión. Úsalo para modificar un usuario que ha iniciado sesión antes de redirigirlo al recurso de IAP. |
En el siguiente código de ejemplo se muestra cómo puedes implementar estas devoluciones de llamada:
callbacks: {
selectTenantUiShown: () => {
// Show info of the IAP resource.
showUiTitle(
'Select your employer to access your Health Benefits');
},
signInUiShown: (tenantId) => {
// Show tenant title and additional display info.
const tenantName = getTenantNameFromId(tenantId);
showUiTitle(`Sign in to access your ${tenantName} Health Benefits`);
},
beforeSignInSuccess: (user) => {
// Do additional processing on user before sign-in is
// complete.
// For example update the user profile.
return user.updateProfile({
photoURL: 'https://example.com/profile/1234/photo.png',
}).then(function() {
// To reflect updated photoURL in the ID token, force token
// refresh.
return user.getIdToken(true);
}).then(function() {
return user;
});
}
}
Inicializar la biblioteca
Una vez que hayas creado un objeto de configuración, sigue estos pasos para inicializar la biblioteca en tu página de autenticación:
Crea un contenedor HTML para renderizar la interfaz de usuario.
<!DOCTYPE html> <html> <head>...</head> <body> <!-- The surrounding HTML is left untouched by FirebaseUI. Your app may use that space for branding, controls and other customizations.--> <h1>Welcome to My Awesome App</h1> <div id="firebaseui-auth-container"></div> </body> </html>
Crea una instancia de
FirebaseUiHandler
para renderizarla en el contenedor HTML y pásale el elementoconfig
que has creado.const configs = { // ... } const handler = new firebaseui.auth.FirebaseUiHandler( '#firebaseui-auth-container', configs);
Crea una instancia de
Authentication
, pásale el controlador y llama astart()
.const ciapInstance = new ciap.Authentication(handler); ciapInstance.start();
Implementa tu aplicación y ve a la página de autenticación. Debería aparecer una interfaz de usuario de inicio de sesión que contenga tus clientes y proveedores.
Siguientes pasos
- Consulte cómo acceder a recursos que no son de Google de forma programática.
- Consulta información sobre cómo gestionar sesiones.
- Consulta más información sobre cómo funcionan las identidades externas con IAP.