Saltar al contenido principal
Al convertir Rules existentes a Actions, debe asociar la nueva Action al Trigger Post-Login (post-login) del flujo de inicio de sesión. Si sigue los pasos que se indican a continuación y mantiene sus Actions en el mismo orden que sus Rules originales, la funcionalidad debería ser idéntica.

Planifique su migración

Las Actions de Post-Login se ejecutan después de las Rules existentes, por lo que puede convertir las Rules una por una en el Dashboard o todas a la vez con la . Tendrá que convertir el código y, después, activar la Action y desactivar la Rule. Activar la Action y desactivar la Rule puede hacerse rápidamente una tras otra, pero, según el orden, podría haber un breve período en el que se estén ejecutando ambas o ninguna. Por este motivo, recomendamos migrar su pipeline paso a paso: convierta partes del código de sus Rules en código de Action, haga pruebas en un entorno de ensayo y, después, pase a producción una parte cada vez. Como las Rules activas se ejecutan antes que las Actions desplegadas, si empieza por el final del pipeline de sus Rules y avanza hacia atrás, puede mantener parte de la lógica en Rules mientras crea y prueba otra lógica en Actions.

Consejos para planificar su migración

  • Mantenga una relación 1:1 entre sus Actions y Rules, para que la funcionalidad pueda activarse y desactivarse por bloques y ponerse a prueba.
  • Use indicadores en los metadatos del usuario para evitar duplicar operaciones costosas o de una sola ejecución.
  • Empiece por el final del pipeline de sus Rules y avance hacia atrás; como las Rules activas se ejecutan antes que las Actions desplegadas, puede mantener parte de la lógica en Rules mientras crea y prueba otra lógica en Actions.
  • Asegúrese de aplicar los cambios en un momento en que el impacto y el tráfico sean mínimos.
  • Considere personalizar temporalmente su página de inicio de sesión para detener los inicios de sesión si el cambio pudiera causar inicios de sesión no válidos o brechas en la protección.
  • Considere usar Auth0 Deploy CLI para crear scripts, probar e implementar rápidamente la migración de una sola vez o de forma iterativa.

Entienda las limitaciones

Aunque Actions puede encargarse de la gran mayoría de las tareas que pueden realizar Rules, debe tener en cuenta algunas limitaciones antes de comenzar la migración. (Recuerde: puede tener tanto Rules como Actions ejecutándose mientras realiza la migración). Para ver la lista completa de limitaciones, consulte Limitaciones de Actions.

Convertir código

Para convertir una Rule en una Action, debe sustituir el código específico de Rules por código de Actions. En esta sección se describen las tareas que deberá realizar para convertir una Rule funcional en su Action equivalente.

Consejos para convertir código

  • En general, busque las propiedades de solo lectura de los objetos user y context de Rules en el objeto event de Actions. Busque en las funciones del objeto api cualquier efecto secundario que sus Actions tengan en el sistema (como hacer fallar un inicio de sesión o actualizar los metadatos del usuario).
  • Use el editor de código de Actions en el Auth0 Dashboard para escribir su código; le ayudará resaltando errores y ofreciendo sugerencias de autocompletado.
  • Antes de pasar a producción, pruebe exhaustivamente sus nuevas Actions en un entorno de ensayo o de prueba.

Copiar el código de la Rule en una nueva Action

Recomendamos copiar el código de su Rule en una nueva Action y usar el editor de código de Actions en el Auth0 Dashboard; esto le ayudará a identificar los problemas pendientes en su código.
  1. Inicie sesión en su inquilino de producción y copie el código de la Rule que desea convertir.
  2. Cambie a un inquilino de no producción y vaya a Auth0 Dashboard > Actions > Library.
  3. Seleccione Build Custom y, a continuación:
    • Introduzca un Name para su Action que coincida con el nombre de la Rule que está convirtiendo.
    • Busque Trigger y seleccione Login / Post Login.
    • Busque Runtime y seleccione Node 16.
    • Seleccione Create.
  4. En el bloque de código del editor de código de Actions, pegue debajo de la función exportada onExecutePostLogin el código de la Rule que desea convertir.
  5. Realice los cambios detallados en el resto de este artículo a medida que incorpora el código en la función.

Cambie la declaración de la función

Las Rules usan una función declarada simple con los parámetros user, context y callback, mientras que las Actions usan una función exportada con un nombre específico. Realice el siguiente cambio; por ahora, ignore los errores que aparezcan. Antes
async function myRulesFunction(user, context, callback) {
    // ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
	// ... código adicional
};

Cambie la forma de acceder a los datos de usuario

En Rules, los datos del usuario que inicia sesión se almacenan en el user object. En Actions, estos datos se encuentran en la propiedad user del event object. La mayoría de las propiedades existentes están disponibles en esta nueva ubicación.
Los datos almacenados o modificados en propiedades del objeto event no están disponibles en otras Actions.
Antes
function myRulesFunction(user, context, callback) {
	const userEmail = user.email;
	const userId = user.user_id;

	// Esta propiedad podría ser undefined en Rules.
	const userAppMetadata = user.app_metadata || {};

	// ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
	const userEmail = event.user.email;
	const userId = event.user.user_id;

	// Esta propiedad nunca será undefined en Actions.
	const userAppMetadata = event.user.app_metadata;

	// ... código adicional
};

Cambie cómo se accede a los datos de contexto

En Rules, los datos de la sesión de inicio de sesión actual se almacenan en el objeto context. En Actions, estos datos se han reestructurado y trasladado al objeto event. Muchas de las propiedades se trasladaron tal cual, pero algunas se combinaron para mejorar la claridad.
Los datos almacenados o modificados en propiedades del objeto event no están accesibles desde otras Actions. Si su Rule desencadena una funcionalidad principal al establecer datos en estas propiedades, como context.idToken o context.multifactor, lea una de las secciones siguientes que aborda su caso de uso.
Antes
function myRulesFunction(user, context, callback) {
	const clientId = context.clientID;
	const clientMetadata = context.clientMetadata || {};

	const connectionId = context.connectionID;
	const connectionMetadata = context.connectionMetadata || {};

	const protocol = context.protocol;

	const tenant = context.tenant;

	// ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
	const clientId = event.client.client_id;
	const clientMetadata = event.client.metadata;

	const connectionId = event.connection.id;
	const connectionMetadata = event.connection.metadata;

	const protocol = event.transaction.protocol;

	const tenant = event.tenant.id;

	// ... código adicional
};

Convertir dependencias

En las Rules, las dependencias se incluyen de una forma que exige indicar el número de versión en una instrucción require. Las Actions usan una sintaxis CommonJS más estándar y requieren que las versiones se indiquen fuera del editor de código. En Rules, solo se permiten versiones concretas de paquetes concretos, y para agregar paquetes o versiones nuevos es necesario enviar una solicitud a Auth0. En Actions, puede usar require con cualquier paquete disponible en el registro de npm.
Si sus módulos de npm no están en la versión más reciente, este es un buen momento para actualizarlos.
  1. Busque las instrucciones require dentro del código de su Rule.
  2. Elimine los números de versión, pero anótelos.
  3. Agregue la dependencia siguiendo los pasos de la sección “Add a Dependency” de Write Your First Action (si la dependencia no es un módulo integrado de NodeJS; si la dependencia es un módulo integrado de NodeJS, no necesita incluirla).
  4. Mueva las instrucciones require encontradas fuera de la declaración function:
Antes
function myRulesFunction(user, context, callback) {
	const dependency = require("dependency@1.2.3");

	// ... código adicional
}
Después
const dependency = require("dependency"); // v1.2.3
exports.onExecutePostLogin = async (event, api) => {
	// ... código adicional
};

Convertir las devoluciones de llamada

Cuando un Rule termina de procesarse, debe llamar a la función callback() y pasar un error si el inicio de sesión falla. En cambio, Actions puede simplemente devolver en caso de éxito o llamar a un método de api con un mensaje si el inicio de sesión falla. Todas las instancias de callback() en un Rule deben eliminarse o sustituirse por api.access.deny() en caso de error. Tanto en Rules como en Actions, si el procesamiento debe detenerse por una condición específica, use una instrucción return. Antes
function myRulesFunction(user, context, callback) {
	const userAppMetadata = user.app_metadata || {};
	if (userAppMetadata.condition === "success") {
		// Este Rule tuvo éxito, continuar con el siguiente Rule.
		return callback(null, user, context);
	}

	if (userAppMetadata.condition === "failure") {
		// Este Rule falló, detener el inicio de sesión con una respuesta de error.
		return callback(new Error("Failure message"));
	}

	// ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
	if (event.user.app_metadata.condition === "success") {
		// Esta Action se realizó correctamente, continuar con la siguiente Action.
		return;
	}

	if (event.user.app_metadata.condition === "failure") {
		// Esta Action falló, detener el inicio de sesión con una respuesta de error.
		return api.access.deny("Failure message");
	}

	// ... código adicional
};

Cambiar la gestión de los secretos

En Rules, los valores de configuración se establecen de forma global, lo que significa que todos los Rules pueden acceder a todos los valores secretos. (Para obtener más información, lea Store Rule Configurations.) En Actions, los valores de configuración se establecen para cada Action individual. No puede acceder al valor secreto de una Action fuera del contexto de esa Action. Para convertir secretos de Rules a Actions:
  1. Guarde los valores necesarios para la Action específica en la que está trabajando.
  2. Agregue un Secret para cada valor al que necesite acceder desde la Action. Para saber cómo hacerlo, lea la sección Add a Secret de Write Your First Action.
  3. Convierta su código:
Antes
function myRulesFunction (user, context, callback) {
  const { CLIENT_ID, CLIENT_SECRET } = configuration;

  // ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
  const { CLIENT_ID, CLIENT_SECRET } = event.secrets;

  // ... código adicional
}
Al igual que con Rules, Auth0 cifra todos los valores secretos almacenados.

Convertir claims personalizadas en los tokens

Tanto Rules como Actions pueden agregar claims personalizadas a los tokens de ID y a los . En Rules, esto es una propiedad del objeto context, mientras que en Actions se usa un método del objeto api. Antes
function myRulesFunction(user, context, callback) {
	const userAppMetadata = user.app_metadata || {};
	const namespace = "https://namespace/";

	context.idToken[`${namespace}/emp_id`] = userAppMetadata.emp_id;
	context.accessToken[`${namespace}/emp_id`] = userAppMetadata.emp_id;

	// ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
	const namespace = "https://namespace/";

	api.idToken.setCustomClaim(
		`${namespace}/emp_id`, 
		event.user.app_metadata.emp_id
	); 		   

	api.accessToken.setCustomClaim(
		`${namespace}/emp_id`, 
		event.user.app_metadata.emp_id
	);

	// ... código adicional
};

Convertir la activación de MFA

En Rules, la se puede activar modificando la propiedad multifactor del objeto context. En Actions, esto se hace con un método del objeto api. Antes
function myRulesFunction(user, context, callback) {
	if (user.app_metadata.needs_mfa === true) {
		context.multifactor = { 
			provider: "any", 
			allowRememberBrowser: false,
		};
	}

	// ... código adicional
}
Después
exports.onExecutePostLogin = async (event, api) => {
	if (event.user.app_metadata.needs_mfa === true) {
		api.multifactor.enable("any", { allowRememberBrowser: false });
	}

	// ... código adicional
};

Convertir las actualizaciones de metadatos de usuario

Para actualizar las propiedades user_metadata y app_metadata en Rules, es necesario hacer una llamada a la Management API, lo que puede provocar errores de límite de tasa. Sin embargo, Actions permite indicar varios cambios en los metadatos de usuario y hacer una sola llamada a la Management API. Antes
function myRulesFunction(user, context, callback) {
	user.app_metadata = user.app_metadata || {}; 
	user.app_metadata.roles = user.app_metadata.roles || [];
	user.app_metadata.roles.push("administrator"); 

	auth0.users
		.updateAppMetadata(user.user_id, user.app_metadata) 
		.then(() => callback(null, user, context))
		.catch((err) => callback(err));

	// ... código adicional
}
Si los Rules posteriores necesitan actualizar los metadatos del usuario, tendrían que llamar a la Management API por separado, lo que aumentaría la probabilidad de alcanzar el límite de tasa. Después
exports.onExecutePostLogin = async (event, api) => {
	const userRolesUpdated = event.user.app_metadata.roles || [];
	userRolesUpdated.push("administrator"); 

	// Nótese el uso de dos métodos diferentes aquí. 
	api.user.setAppMetadata("roles", userRolesUpdated);
	api.user.setUserMetadata("hasRoles", true);

	// ... código adicional
};
Si las Actions posteriores necesitaran actualizar los metadatos del usuario, tendrían que llamar a api.user.setUserMetadata o api.user.setAppMetadata. En Actions, varias llamadas a estas funciones desde una o varias Actions darán lugar a una sola llamada a la Management API una vez que se complete el flujo.

Convertir otras llamadas a la Management API

En general, no recomendamos llamar a la Management API desde una ruta crítica de alto tráfico, como Rules o Actions. Las solicitudes a todas las API de Auth0 están sujetas a límites de tasa, incluidas las llamadas desde puntos de extensibilidad, y llamar a una API en todos los inicios de sesión podría provocar fácilmente errores de inicio de sesión en momentos de mucho tráfico. Sin embargo, si las llamadas son necesarias y están configuradas para evitar los límites de tasa, es posible llamar a la Management API desde Actions. Como se mencionó antes en la sección “Comprender las limitaciones” de este artículo, Actions no recibe un token de acceso para la Management API, por lo que deberá obtener un token de acceso antes de activar su Action:
  1. Registre una aplicación de máquina a máquina y autorícela para la Management API.
  2. Guarde el ID de cliente y el Secreto del cliente en la Action.
  3. Obtenga un token de acceso para la Management API.
  4. Llame a la Management API:
    Actions no puede conservar datos entre ejecuciones, por lo que no es posible almacenar en caché el token de acceso durante ningún período de tiempo; dado que cada llamada a la Management API también requiere una llamada a la Authentication API, llamar a la Management API es una operación muy costosa.
Antes
function myRulesFunction(user, context, callback) {
	const ManagementClient = require("auth0@2.9.1").ManagementClient; 
	const managementClientInstance = new ManagementClient({
		// Estos provienen de las variables globales integradas de Rules
		token: auth0.accessToken, 
		domain: auth0.domain,
	}); 

	managementClientInstance.users.assignRoles(
		{ id: user.user_id }, 
		{ roles: ["ROLE_ID_TO_ADD"] }, 
		(error, user) => {
			if (error) {
				return callback(error);
			}

			// ... código adicional
		}
	);
}
Después
const auth0Sdk = require("auth0");
exports.onExecutePostLogin = async (event, api) => {
	const ManagementClient = auth0Sdk.ManagementClient;

	// Esto realizará una llamada a la Authentication API
	const managementClientInstance = new ManagementClient({
		// Estos provienen de una aplicación machine-to-machine
		domain: event.secrets.M2M_DOMAIN,
		clientId: event.secrets.M2M_CLIENT_ID,
		clientSecret: event.secrets.M2M_CLIENT_SECRET,
		scope: "update:users"
	});

	managementClientInstance.users.assignRoles(
		{ id: event.user.user_id }, 
		{ roles: ["ROLE_ID_TO_ADD"]}, 
		(error, user) => {
			if (error) {
				return api.access.deny(error.message);
			}

			// ... código adicional
		}
	);
};

Convertir redirecciones

Las Rules pueden redirigir a un usuario que está iniciando sesión a una página externa y luego esperar una respuesta. En este caso, todas las Rules anteriores a la redirección se ejecutarán dos veces: una antes de la redirección y otra cuando se reciba la respuesta. La lógica de la redirección y la de la respuesta suelen estar en la misma Rule. En Actions, el pipeline se pausa cuando se produce la redirección y se reanuda cuando el usuario regresa. Además, la función exportada que activa la redirección está separada del callback de redirección.
Explicar cómo realizar correctamente todas las redirecciones en Actions queda fuera del alcance de esta guía. Para obtener información más detallada, consulte Redirect with Actions.
Antes
function myRulesFunction(user, context, callback) {
    if (context.protocol === "redirect-callback") {
        // El usuario fue redirigido al endpoint /continue
        user.app_metadata.wasRedirected = true;
        return callback(null, user, context);
    } else if (
        context.protocol === "oauth2-password" ||
        context.protocol === "oauth2-refresh-token" ||
        context.protocol === "oauth2-resource-owner"
    ) {
        // El usuario no puede ser redirigido
        return callback(null, user, context);
    }
    // El usuario está iniciando sesión directamente
    if (!user.app_metadata.wasRedirected) {
        context.redirect = {
            url: "https://example.com",
        };
        callback(null, user, context);
    }
}
Después
exports.onExecutePostLogin = async (event, api) => {
    api.accessToken.setClaim("https://dev.TLD/wasRedirected", true)

Convertir las referencias actuales de clientes SSO

El objeto context.sso de Rules proporciona información sobre la sesión actual y los clientes que la usan. Para obtener más información, consulta la entrada de context.sso en Propiedades del objeto Context en Rules. En Actions, encontrarás información similar en el objeto event.session. Antes
function (user, context, callback) {

  const clients = context.sso?.current_clients ?? []; 

  if (clients.length > 0) { 
	context.idToken.clients = clients.join(" "); 
  }

  return callback(null, user, context);
}
Después
exports.onExecutePostLogin = async (event, api) => {
  const clients = event?.session?.clients ?? []; 

  if (clients.length > 0) { 
    api.idToken.setCustomClaim('clients', clients.map(c=> c?.client_id).join(" ")); 
  }
};

Complete la migración

Una vez que haya escrito y probado el nuevo código de Actions, debe activar la Action y desactivar la Rule. Estas dos tareas pueden realizarse rápidamente una tras otra, pero, según el orden, podría haber un breve período en el que se ejecuten ambas o ninguna. Dado que las Rules activas se ejecutan antes que las Actions desplegadas, si comienza al final del pipeline de Rules y retrocede, puede mantener parte de la lógica en Rules mientras crea y prueba otra lógica en Actions.