Saltar al contenido principal
La fecha de fin de vida útil (EOL) de Rules y Hooks será el 18 de noviembre de 2026, y ya no están disponibles para los nuevos inquilinos creados a partir del 16 de octubre de 2023. Los inquilinos existentes con Hooks activos conservarán el acceso al producto Hooks hasta su fin de vida útil.Le recomendamos encarecidamente que use Actions para extender Auth0. Con Actions, tiene acceso a información de tipos enriquecida, documentación integrada y paquetes públicos de npm, y puede conectar integraciones externas que mejoran su experiencia general de extensibilidad. Para obtener más información sobre lo que ofrece Actions, lea Understand How Auth0 Actions Work.Para ayudarle con la migración, ofrecemos guías que le ayudarán a migrar de Rules a Actions y migrar de Hooks a Actions. También contamos con una página específica de Move to Actions que destaca comparaciones de funcionalidades, una demostración de Actions y otros recursos para ayudarle en su proceso de migración.Para obtener más información sobre la deprecación de Rules y Hooks, lea nuestra entrada de blog: Preparing for Rules and Hooks End of Life.
En el punto de extensibilidad Client Credentials Exchange, Hooks le permiten ejecutar acciones personalizadas cuando se emite un a través del endpoint POST /oauth/token de la API de autenticación mediante el flujo de credenciales de cliente. Por ejemplo, puede impedir que se emita el token, agregar claims personalizados al token de acceso o modificar sus alcances. Para obtener más información, lea Client Credentials Flow. Los Hooks en este punto de extensibilidad son bloqueantes (sincrónicos), lo que significa que se ejecutan como parte del proceso del activador e impiden que el resto del flujo de Auth0 continúe hasta que el Hook se complete.
El triggerId del punto de extensibilidad Client Credentials Exchange es credentials-exchange. Para aprender a crear Hooks para este punto de extensibilidad, lea Create Hooks.
Para conocer otros puntos de extensibilidad, lea Puntos de extensibilidad.

Código de ejemplo inicial y parámetros

Al crear un Hook que se ejecuta en el punto de extensibilidad Client Credentials Exchange, puede resultarle útil el siguiente código de ejemplo inicial. Los parámetros que se pueden pasar a la función Hook y usar en ella se enumeran al principio del ejemplo de código.
/**
@param {object} client - información del cliente
@param {string} client.name - nombre del cliente
@param {string} client.id - ID de cliente
@param {string} client.tenant - nombre del tenant de Auth0
@param {object} client.metadata - metadatos del cliente
@param {array|undefined} scope - un array de cadenas que representan el claim scope del token, o undefined
@param {string} audience - claim de audiencia del token
@param {object} context - información de contexto de Auth0
@param {object} context.webtask - contexto del Hook (webtask)
@param {function} cb - function (error, accessTokenClaims)
*/

module.exports = function(client, scope, audience, context, cb) {
  var access_token = {};
  access_token.scope = scope; // no eliminar esta línea

  // Modificar alcances o agregar claims adicionales
  // access_token['https://example.com/claim'] = 'bar';
  // access_token.scope.push('extra');

  // Denegar el token y responder con una respuesta de error OAuth2
  // if (denyExchange) {
  //   // Para devolver un HTTP 400 con { "error": "invalid_scope", "error_description": "Not authorized for this scope." }
  //   return cb(new InvalidScopeError('Not authorized for this scope.'));
  //
  //   // Para devolver un HTTP 400 con { "error": "invalid_request", "error_description": "Not a valid request." }
  //   return cb(new InvalidRequestError('Not a valid request.'));
  //
  //   // Para devolver un HTTP 500 con { "error": "server_error", "error_description": "A server error occurred." }
  //   return cb(new ServerError('A server error occurred.'));
  // }

  cb(null, access_token);
};
Tenga en cuenta lo siguiente:
  • La función callback (cb) al final del código de ejemplo indica que la ejecución ha finalizado y debe incluirse.
  • La línea access_token.scope = scope garantiza que todos los alcances concedidos estén presentes en el token de acceso. Si la elimina, se restablecerán todos los alcances y el token incluirá solo los alcances que agregue con el script.

Respuesta predeterminada

Cuando ejecutas un Hook en el punto de extensibilidad Client Credentials Exchange, el objeto de respuesta predeterminado es:
{
  "scope": "array of strings"
}

Respuesta del código base

Una vez que hayas personalizado el código base con tus alcances y claims adicionales, puedes probar el Hook con el ejecutor integrado en el Hook Editor. El ejecutor simula una llamada al Hook con el mismo cuerpo y la misma respuesta que obtendrías con un Client Credentials Exchange.
Ejecutar el código con el ejecutor requiere guardarlo, lo que significa que el código original se sobrescribirá.
Cuando ejecutas un Hook basado en el código base, el objeto de respuesta es:
{
  "audience": "https://my-tenant.auth0.com/api/v2/",
  "client": {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "client-name",
    "tenant": "my-tenant",
    "metadata": {
      "plan": "full"
    }
  },
  "scope": [
    "read:connections"
  ]
}

Script de ejemplo: Añadir un scope adicional al token de acceso

En este ejemplo, usamos un Hook para añadir un scope adicional a los ya existentes en el token de acceso.
module.exports = function(client, scope, audience, context, cb) {
    // Alcances a agregar
    var access_token = {};

    // Obtener el scope que está actualmente en el Token de acceso
    // y agregarlo al objeto con el que estamos trabajando
    // ¡No eliminar esta línea!
    access_token.scope = scope;

    // Agregar el scope `read:resource`
    access_token.scope.push('read:resource');

    // Callback para indicar la finalización y devolver el nuevo
    // arreglo de alcances
    cb(null, access_token);
};
Para obtener más información, consulta Scopes.

Respuesta

Al ejecutar este Hook, el objeto de respuesta es:
{
  "scope": [
    "read:connections",
    "read:resource"
  ]
}

Script de ejemplo: Agregar un claim al token de acceso

En este ejemplo, agregamos un claim personalizado con espacio de nombres y su valor al token de acceso. Para obtener más información, consulta Create Namespaced Custom Claims. Puedes agregar lo siguiente como claims al token emitido:
  • La propiedad scope del objeto de respuesta
  • Cualquier propiedad con nombres de propiedad con espacio de nombres
El punto de extensibilidad ignora todas las demás propiedades del objeto de respuesta.
Para acceder a un Hook Secret configurado desde un hook, usa context.webtask.secrets.SECRET_NAME.
module.exports = function(client, scope, audience, context, cb) {
    // Claims a agregar
    var access_token = {};

    // Nuevo claim para agregar al token
    access_token['https://example.com/foo'] = 'bar';

    // Callback para indicar la finalización y devolver el nuevo claim
    cb(null, access_token);
  };

Respuesta

Al ejecutar este Hook, el objeto de respuesta es:
{
  "https://example.com/foo": "bar"
}

Script de ejemplo: Generar un error o denegar un token de acceso

En este ejemplo, usamos objetos Error personalizados para generar respuestas de error de OAuth2. (Para obtener más información, consulte RFC de OAuth2: sección 5.2 en el IETF Datatracker.) Si se devuelve un error simple de JavaScript en la función de devolución de llamada, como:
module.exports = function(client, scope, audience, context, cb) {
    // Callback para indicar la finalización y devolver el nuevo claim
    cb(new Error("Unknown error occurred.");
  };
Luego, cuando solicites un grant client_credentials al endpoint /oauth/token, Auth0 responderá con:
HTTP 500
{ "error": "server_error", "error_description": "Unknown error occurred." }
Sin embargo, si desea un mayor control sobre la respuesta de error de OAuth2, puede usar en su lugar tres objetos Error personalizados.

InvalidScopeError

module.exports = function(client, scope, audience, context, cb) {
    const invalidScope = ...; // determinar si el scope es válido

    if(invalidScope) {
      cb(new InvalidScopeError("Scope is not permitted."));
    }
  };
Luego, cuando solicitas una concesión client_credentials al endpoint /oauth/token, Auth0 responde con:
HTTP 400
{ "error": "invalid_scope", "error_description": "Scope is not permitted." }

InvalidRequestError

module.exports = function(client, scope, audience, context, cb) {
    const invalidRequest = ...; // determinar si la solicitud es válida

    if(invalidRequest) {
      cb(new InvalidRequestError("Bad request."));
    }
  };
Luego, cuando solicite el grant client_credentials en el endpoint /oauth/token, Auth0 responderá con:
HTTP 400
{ "error": "invalid_request", "error_description": "Bad request." }

ServerError

module.exports = function(client, scope, audience, context, cb) {
    callOtherService(function(err, response) {
      if(err) {
        return cb(new ServerError("Error calling remote system: " + err.message));
      }
    });
  };
Entonces, cuando solicites una concesión de tipo client_credentials al endpoint /oauth/token, Auth0 responderá con:
HTTP 400
{ "error": "server_error", "error_description": "Error calling remote system: ..." }
Actualmente, el comportamiento de la clase integrada Error de JavaScript y de ServerError es idéntico, pero la clase ServerError le permite especificar explícitamente el error de OAuth2 que se devolverá.

Más información