Las Auth0 Actions te permiten personalizar la autenticación con código personalizado. Si usas varios dominios personalizados, puedes acceder a la información del dominio personalizado en tus Actions para implementar lógica específica del dominio, dirigir a los usuarios a organizaciones, aplicar políticas de acceso y personalizar las notificaciones.
Actions permiten acceder a la información del dominio personalizado mediante el objeto event.custom_domain. Este objeto contiene el nombre de dominio y cualquier metadato configurado para ese dominio.
Desencadenadores disponibles
El objeto event.custom_domain está disponible en los siguientes desencadenadores de Actions:
| Desencadenador | Referencia del objeto de evento |
|---|
| Credentials Exchange | Objeto de evento |
| Custom Email Provider | Objeto de evento |
| Custom Phone Provider | Objeto de evento |
| Post Login | Objeto de evento |
| Post User Registration | Objeto de evento |
| Post Password Change | Objeto de evento |
| Pre User Registration | Objeto de evento |
| Reset Password Post Challenge | Objeto de evento |
El objeto event.custom_domain solo está disponible en los desencadenadores en los que la solicitud se origina en un contexto de dominio personalizado. Si no se usó ningún dominio personalizado, esta propiedad será undefined.
Estructura del objeto de evento
Usa el dominio login.example.com configurado con metadatos de dominio:
| Key | Value |
|---|
| allow_list | example1.com,example2.com |
exports.onExecutePostLogin = async (event, api) => {
console.log(event.custom_domain);
};
Se mostraría en la consola:
{
"domain": "login.example.com",
"domain_metadata": {
"allow_list": "example1.com,example2.com"
}
}
Lógica condicional por dominio
Aplique reglas diferentes según se utilice un dominio personalizado o un dominio canónico:
exports.onExecutePostLogin = async (event, api) => {
const domain = event.custom_domain?.domain;
if (
domain === undefined ||
domain.includes('.auth0.com') || // Nube pública
domain.includes('.auth0app.com') // Nube privada
) {
return api.access.deny('Please use the custom domain to log in.');
}
};
Control de acceso basado en dominios de correo electrónico
Aplique políticas de acceso específicas para cada dominio de correo electrónico mediante metadatos de dominio personalizados:
const getEmailDomain = (email) => {
if (!email || typeof email !== 'string') {
return null;
}
const parts = email.split('@');
// Verificar que haya exactamente un '@' (o al menos que exista un dominio)
// maneja casos como "invalid-email" o "user@"
if (parts.length < 2 || !parts[1]) {
return null;
}
return parts[1].toLowerCase().trim();
}
exports.onExecutePreUserRegistration = async (event, api) => {
const domain = event.custom_domain?.domain;
if (domain === undefined) {
return api.access.deny(
'access_denied',
`Access denied - Users cannot access without custom domain.`
);
}
const email = event.user.email;
if (email === undefined) {
return api.access.deny(
'access_denied',
`Access denied - Users cannot access without email.`
);
}
const domainAllowList = event.custom_domain?.domain_metadata?.allow_list?.split(',') || [];
const emailDomain = getEmailDomain(email);
if (domainAllowList.includes(emailDomain) === false) {
return api.access.deny(
'access_denied',
`Access denied - Users from ${emailDomain} cannot access ${domain}.`
);
}
};
Implemente políticas de acceso para grupos de aplicaciones y dominios mediante metadatos de la aplicación y del dominio:
exports.onExecuteCredentialsExchange = async (event, api) => {
const domain = event.custom_domain?.domain;
if (
domain === undefined ||
domain.includes(event.tenant.id)
) {
return; // Omitir para el dominio canónico
}
const applicationGroup = new Set(event.client.metadata?.domain_group?.split(',') || []);
const domainGroup = event.custom_domain?.domain_metadata?.domain_group?.split(',') || [];
const intersection = domainGroup.filter(x => applicationGroup.has(x));
if (intersection.length === 0) {
return api.access.deny(
'invalid_request',
`Access denied - Cannot get access from application ${event.client.name} and ${domain}.`
);
}
};
Aplique políticas de acceso para grupos de conexiones y dominios mediante metadatos de conexión y dominio:
exports.onExecutePostLogin = async (event, api) => {
const domain = event.custom_domain?.domain;
if (domain === undefined) {
return api.access.deny(
`Access denied - Users cannot access without custom domain.`
);
}
const connectionGroup = new Set(event.connection.metadata?.domain_group?.split(',') || []);
const domainGroup = event.custom_domain?.domain_metadata?.domain_group?.split(',') || [];
const intersection = domainGroup.filter(x => connectionGroup.has(x));
if (intersection.length === 0) {
return api.access.deny(
`Access denied - Users cannot access connection ${event.connection.name} from ${domain}.`
);
}
};
Aplique políticas de acceso para grupos de organizaciones y dominios mediante metadatos de la organización y del dominio:
exports.onExecutePostLogin = async (event, api) => {
const organization = event.organization;
if (organization === undefined) {
return; // Omitir para autenticación sin organización
}
const domain = event.custom_domain?.domain;
if (domain === undefined) {
return api.access.deny(
`Access denied - Users cannot access without custom domain.`
);
}
const organizationGroup = new Set(organization.metadata?.domain_group?.split(',') || []);
const domainGroup = event.custom_domain?.domain_metadata?.domain_group?.split(',') || [];
const intersection = domainGroup.filter(x => organizationGroup.has(x));
if (intersection.length === 0) {
return api.access.deny(
`Access denied - Users cannot access organization ${organization.name} from ${domain}.`
);
}
};
Realice solicitudes a servicios externos específicos de cada región en función de los metadatos del dominio personalizado:
exports.onExecuteCustomEmailProvider = async (event, api) => {
const regionServiceEndpoint = event.custom_domain?.domain_metadata?.region_service_endpoint;
if (regionServiceEndpoint === undefined) {
return api.notification.drop(`Missing regional service endpoint configuration at custom domain.`);
}
const notification = event.notification;
const messageBody = {
body: notification.html
};
try {
await fetch(regionServiceEndpoint, {
method: 'POST',
headers: {
'X-API-Key': event.secrets.API_KEY,
},
body: JSON.stringify(messageBody),
});
} catch (err) {
api.notification.drop('External service failure');
}
};
Referencias de objetos de evento