Casos de uso de los metadatos del token de actualización y los metadatos de sesión
Explore implementaciones de ejemplo de casos de uso para los metadatos del token de actualización y los metadatos de sesión.
Los metadatos del token de actualización y los metadatos de sesión permiten, en conjunto, crear y almacenar datos que persisten durante todo el ciclo de vida de la sesión de un usuario en Auth0. Este artículo incluye ejemplos de los siguientes casos de uso:
Los metadatos de sesión de Auth0 no son un almacén de datos seguro y no deben usarse para almacenar información confidencial. Esto incluye secretos e información de identificación personal (PII) de alto riesgo, como números de la seguridad social o de tarjetas de crédito. Se recomienda encarecidamente a los clientes de Auth0 que evalúen los datos almacenados en los metadatos y que solo almacenen lo necesario para fines de gestión de identidades y accesos. Para obtener más información, consulte Auth0 General Data Protection Regulation Compliance.
Los metadatos del token de actualización y los metadatos de la sesión, en conjunto, le permiten crear claims personalizadas persistentes para ampliar la información contenida en los tokens ID y de acceso.Con las claims personalizadas persistentes, puede acceder a datos específicos de la aplicación, como:
Roles de usuario
Permisos
ID de Tenant
Otros atributos necesarios para la autorización y la personalización durante los intercambios de tokens de actualización.
Configure un trigger post-login de Action para crear claims personalizadas persistentes y asignarlas a los metadatos del token de actualización mediante el objeto api.refreshToken.setMetadata().
custom claim Action example
/** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. */exports.onExecutePostLogin = async (event, api) => { let customClaimValue1; let customClaimValue2; // --- Función auxiliar para simular el cálculo de claims personalizados --- // En un escenario real, esta función realizaría lógica compleja // basada en datos de usuario, APIs externas, etc. const calculateCustomClaims = (user) => { // Después de realizar los cálculos, retornar return { claim1: value1, claim2: value2 }; }; // --- Determinar si se trata de un inicio de sesión inicial o un intercambio de token de actualización --- // Si event.request.body.grant_type no es 'refresh_token', probablemente es un inicio de sesión interactivo inicial const isRefreshTokenGrant = event.request.body.grant_type === 'refresh_token'; if (!isRefreshTokenGrant) { // --- Inicio de sesión inicial (p. ej., contraseña, social, MFA-OOB) --- // Calcular los valores de los claims personalizados const calculatedClaims = calculateCustomClaims(event.user); customClaimValue1 = calculatedClaims.claim1; customClaimValue2 = calculatedClaims.claim2; // Almacenar estos valores calculados en los metadatos del Token de actualización para persistencia // Verificar si se emitirá un token de actualización y, de ser así, agregar los metadatosif (event.transaction.requested_scopes.indexOf('offline_access') > -1) {api.refreshToken.setMetadata('customClaim1', customClaimValue1);api.refreshToken.setMetadata('customClaim2', customClaimValue2);} } else { // --- Intercambio de Token de actualización --- // Usar los valores de claims personalizados de los metadatos del Token de actualización customClaimValue1 = event.refresh_token?.metadata?.customClaim1; customClaimValue2 = event.refresh_token?.metadata?.customClaim2; } // --- Por último, agregar los valores determinados como claims personalizados a los tokens --- api.idToken.setCustomClaim('custom_claim_1', customClaimValue1); api.accessToken.setCustomClaim('custom_claim_1', customClaimValue1); api.idToken.setCustomClaim('custom_claim_2', customClaimValue2); api.accessToken.setCustomClaim('custom_claim_2', customClaimValue2);};
Durante un intercambio de token de actualización, una Action post-login posterior puede acceder a estos claims personalizados mediante el objeto event.refresh_token.metadata y aplicarlos a los tokens de actualización recién emitidos con api.idToken.setCustomClaim() y api.accessToken.setCustomClaim().
Una sola Action post-login puede gestionar distintos escenarios de grant_type mediante el objeto event.request.body.grant_type para administrar la persistencia de claims. El objeto event.refresh_token solo está disponible en modo de lectura durante los intercambios de token de actualización.
Los metadatos del token de actualización y los metadatos de la sesión, en conjunto, le permiten crear un ID de sesión único para implementar un identificador de sesión persistente que se conserva durante toda la duración de la sesión de un usuario, incluso durante las rotaciones de tokens de actualización.Con los ID de sesión únicos, puede:
Registrar con precisión la sesión de un usuario para fines de depuración y auditoría.
Proporcionar un mecanismo para que las aplicaciones realicen un seguimiento del estado interno de la sesión.
Permitir que las API ofrezcan registros granulares, limitación de tasa y decisiones de autorización contextuales.
Aplicar experiencias de UX coherentes que abarquen varios ciclos de vida de los tokens.
Configure un trigger de Action de post-login para crear un ID de sesión único y asignarlo a la sesión del usuario mediante los objetos api.session.setMetadata() y api.refreshToken.setMetadata().Agregue el ID de sesión único como un claim personalizado al ID Token y al token de acceso mediante los objetos api.idToken.setCustomClaim() y api.accessToken.setCustomClaim().
unique session ID Action example
/** * @param {Event} event - Detalles sobre el usuario y la transacción de autenticación. * @param {PostLoginActionAPI} api - Interfaz para modificar la transacción de autenticación completada. */exports.onExecutePostLogin = async (event, api) => { let sessionId; // 1) Verificar si ya existe una clave de metadatos de sesión llamada 'ses_id'. if (event.session && event.session.metadata && event.session.metadata.ses_id) { sessionId = event.session.metadata.ses_id; } // Si no se encuentra en los metadatos de sesión, verificar si está disponible en los metadatos del token de actualización. // Esto es especialmente relevante para flujos ROPG en los que no hubo una sesión real. else if (event.refresh_token && event.refresh_token.metadata && event.refresh_token.metadata.ses_id) { sessionId = event.refreshToken.metadata.ses_id; } // Si no existe un 'ses_id', generar uno nuevo if (!sessionId) { sessionId = generateSesId(); // Función auxiliar propia para generar un UUID // Almacenar el 'ses_id' recién generado en los metadatos de sesión. // Hacer esto solo si hay una sesión presente o siendo emitida en el evento. if (event.session) { api.session.setMetadata('ses_id', sessionId); } // Almacenar el 'ses_id' en los metadatos del token de actualización. // Hacer esto solo si hay un token de actualización presente o siendo emitido en el evento. if (event.refresh_token) { api.refreshToken.setMetadata('ses_id', sessionId); } } else { // Además, asegurarse de que los metadatos del token de actualización contengan el ses_id, por si faltaba // o fue actualizado en otro lugar. Esto puede ocurrir si el usuario no solicitó offline_access inicialmente pero lo agregó después. if (event.refresh_token && event.refresh_token.metadata && !event.refresh_token.metadata.ses_id) { api.refreshToken.setMetadata('ses_id', sessionId); } } // 2) Agregar este 'ses_id' como claim personalizado tanto al ID Token como al token de acceso. api.idToken.setCustomClaim('ses_id', sessionId); api.accessToken.setCustomClaim('ses_id', sessionId);};
Durante un intercambio de un Token de actualización, una trigger posterior de la Action de post-login puede acceder a estas claims personalizadas mediante el objeto event.refresh_token.metadata y aplicarlas a los tokens de actualización recién emitidos mediante los objetos api.idToken.setCustomClaim() y api.accessToken.setCustomClaim().
Los metadatos del token de actualización y los metadatos de la sesión, en conjunto, le permiten crear un identificador de inquilino persistente para administrar aplicaciones multiinquilino, en las que una sola instancia de la aplicación da servicio a varias organizaciones de clientes y se mantiene durante toda la duración de la sesión del usuario.Con un identificador de inquilino persistente, puede:
Agregar control de acceso dinámico para aplicar fácilmente permisos específicos del inquilino en sus aplicaciones y API
Crear una experiencia de usuario personalizada para ofrecer contenido y funciones relevantes para el contexto de inquilino actual del usuario
Simplificar la lógica multiinquilino al centralizar la identificación y propagación del inquilino dentro de Auth0
Mejorar la seguridad al evitar la exposición accidental de datos entre inquilinos, garantizando un contexto de inquilino coherente en todos los tokens
Mejorar la escalabilidad al reducir la necesidad de hacer consultas repetidas a la base de datos o de usar lógica compleja para determinar el contexto del inquilino en cada llamada a la API o actualización del token
Configure un trigger de Action de post-login para identificar el inquilino activo del usuario, ya sea consultando en la aplicación un valor ext-tenantId proporcionado durante la solicitud de autenticación, infiriendo el inquilino mediante geolocalización o pidiendo al usuario que seleccione el inquilino que desea usar.Una vez identificado el inquilino, asigne el valor del identificador del inquilino a la sesión del usuario mediante los objetos api.session.setMetadata() y api.refreshToken.setMetadata(), y agrégelo como un claim personalizado al token de ID y al token de acceso mediante los objetos api.idToken.setCustomClaim() y api.accessToken.setCustomClaim().
tenant identifier Action example
/** * @param {Event} event - Detalles sobre el usuario y la transacción de autenticación. * @param {PostLoginActionAPI} api - Interfaz para modificar la transacción de autenticación completada. */exports.onExecutePostLogin = async (event, api) => { let tenantId; // 1) Verificar si ya existe una clave de metadatos de sesión llamada 'tenant_id'. if (event.session && event.session.metadata && event.session.metadata.tenant_id) { tenantId = event.session.metadata.tenant_id; } // Si no se encuentra en los metadatos de sesión, verificar si está disponible en los metadatos del token de actualización. // Esto es especialmente relevante para flujos ROPG donde no hubo una sesión real. else if (event.refresh_token && event.refresh_token.metadata && event.refresh_token.metadata.tenant_id) { tenantId = event.refreshToken.metadata.tenant_id; } // Si aún no conocemos el 'tenant_id', lo determinamos if (!tenantId) { // Se asume que tenant_id llegó como parámetro ext- tenantId = event.request.query['ext-tenantId']; // También podría provenir de la geolocalización en el evento // o de formularios. Si se usan formularios, se abriría el formulario // ahora y se ejecutaría el resto del código en la // función onContinuePostLogin // Almacenar el 'tenant_id' recién obtenido en los metadatos de sesión // Solo hacer esto si realmente se está emitiendo/existe una sesión en el evento. if (event.session) { api.session.setMetadata('tenant_id', tenantId); } // Almacenar el 'tenant_id' en los metadatos del token de actualización. // Solo hacer esto si realmente se está emitiendo/existe un token de actualización en el evento. if (event.refresh_token) { api.refreshToken.setMetadata('tenant_id', tenantId); } } else { // Además, asegurarse de que los metadatos del token de actualización contengan el tenant_id, por si estaba ausente // o fue actualizado en otro lugar. Esto puede ocurrir si el usuario no solicitó offline_access inicialmente pero lo agregó después. if (event.refresh_token && event.refresh_token.metadata && !event.refresh_token.metadata.tenant_id) { api.refreshToken.setMetadata('tenant_id', tenantId); } } // 2) Agregar este 'tenant_id' como claim personalizado tanto al ID Token como al token de acceso. api.idToken.setCustomClaim('tenant_id', tenantId); api.accessToken.setCustomClaim('tenant_id', tenantId);};
Durante un intercambio de Token de actualización, una Action posterior de post-login puede acceder a estos claims personalizados mediante el objeto event.refresh_token.metadata y aplicarlos a los tokens de actualización recién emitidos con api.idToken.setCustomClaim() y api.accessToken.setCustomClaim().
Administra datos transitorios de proveedores de identidad (IdP) de origen
Los metadatos del Token de actualización y los metadatos de la sesión te permiten gestionar datos transitorios y contextuales de IdP de origen durante toda la sesión de un usuario sin almacenarlos de forma permanente en su perfil de Auth0.Con los datos transitorios, puedes:
Mantener limpios los perfiles de usuario al evitar almacenar datos transitorios o específicos de la sesión
Mejorar la flexibilidad al admitir distintos requisitos de datos de varios IdP sin forzar cambios de esquema ni sobrecargar los perfiles de usuario persistentes
Mejorar el cumplimiento al facilitar la adhesión a las políticas de privacidad y retención de datos, almacenando los datos transitorios solo durante el tiempo necesario
Reducir la carga de desarrollo al simplificar el proceso de gestión de datos transitorios de IdP, ya que Auth0 Actions y los metadatos administran el ciclo de vida de los datos
Configura un trigger de Action de post-login para identificar los datos del perfil de usuario contenidos en los objetos event.request, event.user y event.context.Determina qué datos son transitorios o contextuales y asígnalos a la sesión del usuario mediante api.session.setMetadata() y api.refreshToken.setMetadata(). Agrega los datos transitorios como una claim personalizada al token de ID y al token de acceso mediante api.idToken.setCustomClaim() y api.accessToken.setCustomClaim().
transient data Action example
/** * @param {Event} event - Detalles sobre el usuario y la transacción de autenticación. * @param {PostLoginActionAPI} api - Interfaz para modificar la transacción de autenticación completada. */exports.onExecutePostLogin = async (event, api) => { let deviceIdentifier; let groups; // Ejemplo: Extraer información del dispositivo de los encabezados de solicitud o del contexto // Esto es ilustrativo; la identificación real del dispositivo puede ser más compleja if (event.request.user_agent) { deviceIdentifier = event.request.user_agent; } else { deviceIdentifier = 'unknown'; } // Ejemplo: Extraer información del IdP del contexto de una conexión ascendente // Esto depende en gran medida del IdP ascendente y de cómo transmite la información. // Se asume un claim personalizado o variable de contexto de una conexión SAML/OIDC, p. ej. "groups" if (event.user.groups) { groups = event.user.groups; } else { groups = []; } // Almacenar los datos transitorios en los metadatos de sesión api.session.setMetadata('deviceIdentifier', deviceIdentifier); api.session.setMetadata('groups', groups); // Almacenar los datos transitorios en los metadatos del token de actualización para mantener la persistencia entre actualizaciones if (event.refreshToken) { api.refreshToken.setMetadata('deviceIdentifier', deviceIdentifier); api.refreshToken.setMetadata('groups', groups); } // Opcionalmente, agregar estos como claims a los tokens de acceso si las APIs los requieren // Usar espacios de nombres personalizados es una buena práctica para claims específicos de la aplicación. api.accessToken.setCustomClaim('https://myapp.example.com/device_id', deviceIdentifier); api.accessToken.setCustomClaim('https://myapp.example.com/groups', groups); // Ejemplo: Si el IdP ascendente proporciona un "nivel de garantía" para este evento de autenticación if (event.transaction && event.transaction.acr_values) { // acr: Authentication Context Class Reference (Referencia de clase de contexto de autenticación) api.session.setMetadata('authLevel', event.transaction.acr_values); if (event.refreshToken) { api.refreshToken.setMetadata('authLevel', event.transaction.acr_values); } api.accessToken.setCustomClaim('https://myapp.example.com/auth_level', event.transaction.acr_values); }};
Durante un intercambio de un Token de actualización, un trigger posterior de Action post-login puede acceder a estas claims personalizadas mediante el objeto event.refresh_token.metadata y aplicarlas a los tokens de actualización recién emitidos mediante el objeto api.accessToken.setCustomClaim().
Los metadatos del token de actualización y los metadatos de la sesión, en conjunto, le permiten implementar seguridad adaptativa, ya que hacen posible rastrear y comparar información contextual a lo largo de la sesión de un usuario, incluidas las rotaciones del token de actualización y las solicitudes de autenticación silenciosa.Al implementar seguridad adaptativa, puede:
Crear una detección proactiva de amenazas mediante la identificación y respuesta automáticas ante cambios sospechosos en los datos de contexto del usuario, lo que reduce el riesgo de secuestro de sesión y acceso no autorizado.
Reducir la fricción para los usuarios legítimos solicitando MFA o verificación adicional solo cuando se detecte una anomalía real, lo que mejora la experiencia del usuario en comparación con los requisitos generales de MFA.
Configure un trigger de Action de post-login para identificar datos contextuales del usuario, que pueden incluir la huella digital del dispositivo, la ubicación geográfica, los atributos de red y los atributos de comportamiento. Almacene los datos contextuales para compararlos en la sesión del usuario mediante el objeto api.session.setMetadata().
security detection Action example
/** * @param {Event} event - Detalles sobre el usuario y la transacción de autenticación. * @param {PostLoginActionAPI} api - Interfaz para modificar la transacción de autenticación completada. */exports.onExecutePostLogin = async (event, api) => { // --- Capturar los datos contextuales actuales --- // Usar las huellas digitales ja3/ja4 proporcionadas por Auth0 const {ja3, ja4} = event.security_context; // Agregar ja3/ja4 a los metadatos si aún no están presentes // (el primer inicio de sesión no tiene metadatos configurados) if (event.session && !event.session.metadata) { api.session.setMetadata('ja3', ja3); api.session.setMetadata('ja4', ja4); } else { // Comparar la huella digital almacenada con la huella digital entrante if(ja3 != event.session?.metadata?.ja3 || ja4 != event.session?.metadata?.ja4) { // Si las huellas digitales difieren, solicitar MFA api.authentication.challengeWith( { type: 'otp'}, { additionalFactors: [ { type: 'push-notification'}, { type: 'phone' } ]} ); } }};
Durante un intercambio de Token de actualización o una autenticación silenciosa, la ejecución posterior de una post-login Action puede aplicar una evaluación de riesgos y respuestas adaptativas.
Puede usar los endpoints GET de la Management API de Auth0 /api/v2/refresh-tokens/{id} y /api/v2/sessions/{id} para recuperar los datos almacenados en los metadatos de un Token de actualización o de una sesión.La respuesta incluye el campo metadata, que contiene los datos almacenados: