Saltar al contenido principal
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.

Acceder a la información del dominio personalizado

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:
DesencadenadorReferencia del objeto de evento
Credentials ExchangeObjeto de evento
Custom Email ProviderObjeto de evento
Custom Phone ProviderObjeto de evento
Post LoginObjeto de evento
Post User RegistrationObjeto de evento
Post Password ChangeObjeto de evento
Pre User RegistrationObjeto de evento
Reset Password Post ChallengeObjeto 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:
KeyValue
allow_listexample1.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"
  }
}

Casos de uso habituales

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

Control de acceso basado en metadatos de la aplicación

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

Control de acceso basado en metadatos de conexión

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

Control de acceso basado en metadatos de la organización

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

Solicitudes por región

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

Más información

Documentación de Actions

Referencias de objetos de evento