> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Aprende a usar Demonstrating Proof-of-Possession (DPoP) para restringir al remitente los tokens de acceso en Auth0.

# Demonstrating Proof-of-Possession (DPoP)

Demonstrating Proof-of-Possession (DPoP) es una [extensión de OAuth 2.0](https://datatracker.ietf.org/doc/draft-ietf-oauth-dpop/) que vincula o [restringe al remitente](/es/docs/secure/sender-constraining) los <Tooltip tip="Token de acceso: Credencial de autorización, en forma de una cadena opaca o un JWT, usada para acceder a una API." cta="Ver glosario" href="/es/docs/glossary?term=access+tokens">tokens de acceso</Tooltip> mediante criptografía asimétrica y <Tooltip tip="Token de acceso: Credencial de autorización, en forma de una cadena opaca o un JWT, usada para acceder a una API." cta="Ver glosario" href="/es/docs/glossary?term=JSON+Web+Tokens">JSON Web Tokens</Tooltip> (JWT) en la capa de aplicación. DPoP garantiza que solo la aplicación cliente que solicitó el token de acceso y que posee la clave privada pueda usarlo. Esto evita el uso indebido de tokens robados.

DPoP usa una clave pública/privada para crear una prueba DPoP como un JSON Web Token (JWT) firmado. La prueba DPoP contiene:

* La clave pública del cliente (`jwk`).
* La carga útil que hace referencia a la solicitud del token de acceso, incluido el método (`htm`) y el URI (`htu`).
* Una firma creada con la clave privada del cliente.
* Un ID único (`jti`) para evitar ataques de repetición.
* Para cada solicitud a la API, un hash SHA-256 (`ath`) del token de acceso codificado en base64url.
* Opcional: Para <Tooltip tip="Cliente público: Cliente (aplicación) que no puede almacenar credenciales de forma segura. Algunos ejemplos son una aplicación nativa de escritorio o móvil y una aplicación web del lado del cliente basada en JavaScript (como una single-page app (SPA))." cta="Ver glosario" href="/es/docs/glossary?term=public+clients">clientes públicos</Tooltip>, un claim `nonce` para garantizar que la aplicación cliente haya generado recientemente el JWT de prueba de DPoP.

La aplicación cliente envía el JWT de prueba de DPoP en una solicitud de token de acceso al <Tooltip tip="Servidor de autorización: Servidor centralizado que contribuye a definir los límites del acceso de un usuario. Por ejemplo, su servidor de autorización puede controlar los datos, tareas y funciones disponibles para un usuario." cta="Ver glosario" href="/es/docs/glossary?term=Authorization+Server">Servidor de autorización</Tooltip> de Auth0. Después de que el Servidor de autorización de Auth0 valide el JWT de prueba de DPoP, vincula el token de acceso emitido a la clave pública del cliente.

<div id="common-use-cases">
  ## Casos de uso comunes
</div>

Conozca algunos casos de uso comunes de DPoP:

* **Aplicaciones de página única (SPA) y aplicaciones móviles:** Como clientes públicos, las SPA y las aplicaciones móviles carecen de un entorno confiable y confidencial, como el de un servidor backend, para almacenar de forma segura <Tooltip tip="Client Secret: Secreto utilizado por un cliente (aplicación) para autenticarse con el Servidor de autorización; solo deberían conocerlo el cliente y el Servidor de autorización, y debe ser lo suficientemente aleatorio como para que no pueda adivinarse." cta="Ver glosario" href="/es/docs/glossary?term=client+secrets">secretos del cliente</Tooltip>, lo que las hace vulnerables al robo de tokens. DPoP aborda esta vulnerabilidad de seguridad vinculando los tokens de acceso a la clave pública de la aplicación cliente y creando un JWT de prueba de DPoP. La aplicación cliente firma el JWT de prueba de DPoP con su clave privada y lo envía en una solicitud de autorización. El Servidor de autorización de Auth0 valida el JWT de prueba de DPoP y, si es válido, vincula el token de acceso emitido a la clave pública del cliente.
* **Integraciones con API de terceros:** Si un agente de IA integrado con su aplicación cliente llama a una API de terceros en nombre del usuario mediante un JWT de prueba de DPoP, entonces el <Tooltip tip="Resource Server: Servidor que aloja recursos protegidos. Los servidores de recursos aceptan y responden a solicitudes de recursos protegidos." cta="Ver glosario" href="/es/docs/glossary?term=resource+server">servidor de recursos</Tooltip> puede validar criptográficamente que la solicitud proviene del agente de IA y no de un tercero no autorizado.

<div id="supported-application-grant-types">
  ## Tipos de concesión de aplicación compatibles
</div>

Auth0 admite los siguientes [tipos de concesión de aplicación](/es/docs/get-started/applications/application-grant-types) para Sender Constraining con DPoP:

| Tipo de concesión                                     | Descripción                                                                                                                                                 |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorization_code`                                  | Concesión de código de autorización                                                                                                                         |
| `client_credentials`                                  | Concesión de credenciales de cliente                                                                                                                        |
| `password`                                            | Concesión de contraseña del propietario del recurso                                                                                                         |
| `refresh_token`                                       | Concesión de Token de actualización                                                                                                                         |
| `urn:ietf:params:oauth:grant-type:device_code`        | Concesión de autorización de dispositivo                                                                                                                    |
| `http://auth0.com/oauth/grant-type/password-realm`    | Utiliza una concesión de extensión similar a la concesión de contraseña del propietario del recurso que incluye la capacidad de indicar un realm específico |
| `http://auth0.com/oauth/grant-type/passwordless/otp`  | Solicitud de concesión sin contraseña                                                                                                                       |
| `http://auth0.com/oauth/grant-type/mfa-oob`           | Solicitud de concesión OOB de Autenticación multifactor                                                                                                     |
| `http://auth0.com/oauth/grant-type/mfa-otp`           | Solicitud de concesión OTP de Autenticación multifactor                                                                                                     |
| `http://auth0.com/oauth/grant-type/mfa-recovery-code` | Solicitud de concesión de código de recuperación de Autenticación multifactor                                                                               |
| `urn:ietf:params:oauth:grant-type:token-exchange`     | Solicitud de concesión de Custom Token Exchange                                                                                                             |
| `urn:okta:params:oauth:grant-type:webauthn`           | Solicitud de concesión de WebAuthn                                                                                                                          |

<div id="how-it-works">
  ## Cómo funciona
</div>

El siguiente diagrama de secuencia ilustra los pasos generales del flujo DPoP de Auth0:

<Frame>
  <img src="https://mintcdn.com/translations/mMSz-RNYLuOm2GmQ/docs/images/cdy7uua7fh8z/XoEV4y12QtnGwBPCiFbep/6744ab830ab2119664463f8c52fe6b02/Screenshot_2025-07-28_at_11.15.42_AM.png?fit=max&auto=format&n=mMSz-RNYLuOm2GmQ&q=85&s=c75e773654d080a4fc99cf1a6b0e0ebe" alt="" width="1256" height="600" data-path="docs/images/cdy7uua7fh8z/XoEV4y12QtnGwBPCiFbep/6744ab830ab2119664463f8c52fe6b02/Screenshot_2025-07-28_at_11.15.42_AM.png" />
</Frame>

1. Al solicitar un token de acceso al Servidor de autorización de Auth0, la aplicación cliente genera un par de claves criptográficas único y usa la clave pública para demostrar que posee la clave privada.
2. La aplicación cliente genera el JWT de prueba de DPoP y lo envía al endpoint /token del Servidor de autorización de Auth0.
3. El Servidor de autorización de Auth0 verifica el JWT de prueba de DPoP y, si es válido, emite el token de acceso y lo vincula a la clave pública del cliente.
4. Antes de llamar a la API del cliente, la aplicación cliente genera un nuevo JWT de prueba de DPoP para demostrar que posee la clave privada asociada al token. La aplicación cliente envía el JWT de prueba de DPoP y el token de acceso restringido al remitente al servidor de recursos.
5. El servidor de recursos verifica el JWT de prueba de DPoP, lo que garantiza que solo el propietario legítimo del token, o la aplicación cliente original, pueda usarlo para acceder correctamente a recursos protegidos. Para solicitar un token de acceso a partir de un token de actualización, la aplicación cliente genera un nuevo JWT de prueba de DPoP, lo que garantiza que el token de actualización quede vinculado a la clave pública del cliente.

<div id="sender-constrain-tokens-using-dpop-in-auth0">
  ## Aplicar restricción del remitente a los tokens mediante DPoP en Auth0
</div>

El siguiente diagrama muestra el flujo de extremo a extremo para aplicar restricción del remitente a los tokens mediante DPoP en Auth0:

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7sonusMpvBMP0fDS6OkXSA/7cd0d50ffc44167f52f7e29d7f723d4a/Screenshot_2025-07-28_at_11.17.43_AM.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=5a29d50e0213083c972c089629ca9b2f" alt="" width="1272" height="806" data-path="docs/images/cdy7uua7fh8z/7sonusMpvBMP0fDS6OkXSA/7cd0d50ffc44167f52f7e29d7f723d4a/Screenshot_2025-07-28_at_11.17.43_AM.png" />
</Frame>

Las siguientes secciones le guían paso a paso por el flujo de DPoP en Auth0 con ejemplos de código para implementarlo:

* [Requisitos previos](#prerequisites)
* [Paso 1: La aplicación cliente genera un par de claves de DPoP](#step-1-client-application-generates-a-dpop-key-pair)
* [Paso 2: La aplicación cliente crea un JWT de prueba de DPoP](#step-2-client-application-creates-a-dpop-proof-jwt)
* [Paso 3: La aplicación cliente solicita un token vinculado a DPoP](#step-3-client-application-requests-a-dpop-bound-token)
* [Paso 4: El Servidor de autorización de Auth0 valida el JWT de prueba de DPoP](#step-4-auth0-authorization-server-validates-the-dpop-proof-jwt)
* [Paso 5: La aplicación cliente llama a la API con el token vinculado a DPoP y el JWT de prueba de DPoP](#step-5-client-application-calls-api-with-the-dpop-bound-token-and-dpop-proof-jwt)
* [Paso 6: Gestionar la renovación de tokens con DPoP](#step-6-handle-token-refresh-with-dpop)

<div id="prerequisites">
  ## Requisitos previos
</div>

Antes de comenzar, asegúrate de haber hecho lo siguiente:

* [Configurar la restricción del remitente](/es/docs/secure/sender-constraining/configure-sender-constraining) para tu aplicación cliente y tu servidor de recursos.

<div id="step-1-client-application-generates-a-dpop-key-pair">
  ## Paso 1: La aplicación cliente genera un par de claves DPoP
</div>

Para DPoP, la aplicación cliente debe generar un par de claves criptográficas asimétricas. Auth0 admite el uso de curvas elípticas, como las claves ES256. Este par de claves es exclusivo de su aplicación cliente y debe almacenarse de forma segura, por ejemplo, en un almacén de claves respaldado por hardware.

La aplicación cliente mantiene la clave privada en secreto e incluye la clave pública en el JSON Web Token (JWT) de prueba de DPoP, que actúa como la “prueba de posesión” en el [Paso 2](#step-2-client-application-creates-a-dpop-proof-jwt).

<div id="step-2-client-application-creates-a-dpop-proof-jwt">
  ## Paso 2: La aplicación cliente crea un JWT de prueba de DPoP
</div>

Antes de solicitar un token de acceso vinculado a DPoP en el endpoint `/token` del Servidor de autorización de Auth0, tu aplicación cliente debe crear un JWT de prueba de DPoP. Un JWT de prueba de DPoP es un JSON Web Token (JWT) firmado con la clave privada de tu cliente que actúa como la «prueba de posesión».

El JWT de prueba de DPoP consta de un encabezado JWT y una carga útil que contiene [claim](/es/docs/secure/tokens/json-web-tokens/json-web-token-claims) vinculadas a la solicitud del token:

<div id="jwt-header-claims">
  ### claim del encabezado del JWT
</div>

| Claim de prueba JWT de DPoP | Descripción                                                                 |
| --------------------------- | --------------------------------------------------------------------------- |
| `typ`                       | Se establece en `dpop+jwt`.                                                 |
| `alg`                       | El algoritmo de firma asimétrica utilizado, como `RS256` o `ES256`.         |
| `jwk`                       | Una representación de JSON Web Key (JWK) de la clave pública de su cliente. |

<div id="jwt-payload-claims">
  ### claim de la carga útil del JWT
</div>

| Claim del JWT de prueba de DPoP | Descripción                                                                                                                                                                                                                         |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `jti`                           | Un identificador único del JWT para evitar ataques de repetición.                                                                                                                                                                   |
| `htm`                           | El método HTTP de la solicitud para la que se genera la prueba DPoP, como `POST` para solicitudes de token y `GET` para llamadas a la API.                                                                                          |
| `htu`                           | El URI HTTP de la solicitud para la que se genera el JWT de prueba de DPoP, sin el fragmento ni los parámetros de consulta. Por ejemplo: `https://api.example.com/data?param=1#section1` pasa a ser `https://api.example.com/data`. |
| `iat`                           | La marca de tiempo de creación del JWT.                                                                                                                                                                                             |
| `ath`                           | Para llamadas a la API con un token de acceso, un hash SHA-256 del token de acceso codificado en base64url.                                                                                                                         |
| `nonce`                         | Para clientes públicos que requieren un `nonce`, un valor `nonce` proporcionado por el servidor.                                                                                                                                    |

Una vez que la aplicación cliente crea el JWT de prueba de DPoP, lo firma con la clave privada generada en [Paso 1](#step-1-client-application-generates-a-dpop-key-pair).

El siguiente ejemplo de código muestra cómo crear y firmar un JWT de prueba de DPoP en la aplicación cliente:

```jsx lines theme={null}
import { generateKeyPairSync, randomBytes } from 'node:crypto';
import jwt from 'jsonwebtoken';

// Generar un par de claves DPoP
const keyPair = generateKeyPairSync('ec', {
  namedCurve: 'P-256',
});

// Construir el JWT de prueba DPoP para la solicitud de token
const jti = randomBytes(16).toString('base64url');
const jwk = keyPair.publicKey.export({ format: 'jwk' });
const dpopHeader = jwt.sign({
    jti,
    htm: 'POST',
    htu: 'https://[TENANT]/oauth/token',
    iat: Date.now() / 1000,
  },
  keyPair.privateKey,
  {
    algorithm: 'ES256',
    header: {
      typ: 'dpop+jwt',
      jwk,
    },
  });
```

<div id="step-3-client-application-requests-a-dpop-bound-token">
  ## Paso 3: La aplicación cliente solicita un token vinculado a DPoP
</div>

Cuando la aplicación cliente solicita un token de acceso al endpoint `/token` del Servidor de autorización de Auth0, incluye la prueba JWT de DPoP en el encabezado HTTP de la solicitud:

```http lines theme={null}
DPoP: {DPoP_proof_JWT_value}
```

A continuación se muestra un ejemplo de solicitud de token de acceso que incluye el encabezado HTTP DPoP con un JWT de prueba de DPoP:

```http lines theme={null}
POST /oauth/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: {DPoP Proof JWT}
Authorization: Basic Y2xpZW50MTIzOm15c2VjcmV0
Cache-Control: no-cache
grant_type=client_credentials&client_id=client123
```

Para implementar la solicitud de un token de acceso vinculado a DPoP en su aplicación cliente, use el siguiente ejemplo de código, que hace lo siguiente:

1. Rellena el encabezado HTTP DPoP con un JWT de prueba de DPoP firmado.
2. Envía el encabezado HTTP DPoP con un JWT de prueba de DPoP firmado en una solicitud de token de acceso al endpoint `/token`.
3. Procesa la respuesta del Servidor de autorización de Auth0.

```javascript lines theme={null}
// Realiza la solicitud al endpoint /oauth/token
// Reemplaza [...] con tu grant_type, client_id y URL de tenant reales
const response = await fetch('https://[TENANT]/oauth/token', {
    method: 'POST',
    body: new URLSearchParams({
      grant_type: '...',
      client_id: '...',
      // Otros parámetros del cuerpo aquí
    }),
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      // Agrega el encabezado DPoP
      dpop: dpopHeader
    }
  });

// Procesa la respuesta del Servidor de autorización de Auth0
const result = await response.json();
console.log('Initial token request result:', result);
```

<div id="public-clients">
  ### Clientes públicos
</div>

Si un cliente público, como una aplicación de una sola página (SPA) o una aplicación móvil, solicita un token de acceso vinculado a DPoP, no tendrá un secreto del cliente ni otros parámetros de autenticación del cliente. En este caso, y de acuerdo con [RFC 9449](https://datatracker.ietf.org/doc/html/rfc9449#section-8), Auth0 exige que el encabezado HTTP DPoP incluya un valor de <Tooltip tip="Nonce: Número arbitrario emitido una vez en un protocolo de autenticación para detectar y prevenir ataques de repetición." cta="Ver glosario" href="/es/docs/glossary?term=nonce">nonce</Tooltip> para garantizar que la aplicación cliente haya generado recientemente el JWT de prueba de DPoP. Este es el comportamiento esperado, ya que permite al Servidor de autorización asegurarse de que la prueba de DPoP sea reciente y limita el período durante el que puede usarse.

Si un cliente público realiza una solicitud a `/token` y no incluye un valor `nonce` en el encabezado HTTP DPoP, Auth0 responde con un código `HTTP 400` y un mensaje de error como el siguiente:

```js lines theme={null}
{
  error: 'use_dpop_nonce',
  error_description: 'El servidor de autorización requiere nonce en la prueba DPoP'
}
```

Auth0 incluye el encabezado `DPoP-Nonce` en los encabezados de respuesta. Esto sigue el flujo estándar de "desafío-respuesta" definido en la [especificación de DPoP](https://datatracker.ietf.org/doc/html/rfc9449). Debe usar el valor del encabezado `DPoP-Nonce` y volver a generar la prueba DPoP (como en el [Paso 2](#step-2-client-application-creates-a-dpop-proof-jwt)), incluir un claim `nonce` con ese valor y volver a enviar la solicitud al endpoint `/token`.

El siguiente ejemplo de código muestra el flujo completo al realizar y luego reintentar una solicitud a `/token` con un claim `nonce` desde un cliente público:

```jsx lines expandable theme={null}
import { generateKeyPairSync, randomBytes } from 'node:crypto';
import jwt from 'jsonwebtoken';

// Generar un par de claves DPoP
const keyPair = generateKeyPairSync('ec', {
  namedCurve: 'P-256',
});

/**
 * Función auxiliar para generar un JWT de prueba de DPoP.
 * @param {string} method - Método HTTP (p. ej., 'POST', 'GET').
 * @param {string} url - URL completa de la solicitud.
 * @param {string} [nonce] - Valor DPoP-Nonce opcional del servidor.
 * @param {string} [accessToken] - Token de acceso opcional para calcular el hash del claim 'ath'.
 * @returns {string} El JWT de prueba de DPoP firmado.
 */
function generateDPoPHeader(method, url, nonce) {
  const jti = randomBytes(16).toString('base64url');
  const jwk = keyPair.publicKey.export({ format: 'jwk' });
  return jwt.sign({
      jti,
      htm: method,
      htu: url,
      iat: Date.now() / 1000,
      nonce
    },
    keyPair.privateKey,
    {
      algorithm: 'ES256',
      header: {
        typ: 'dpop+jwt',
        jwk,
      },
    });
  }

// Solicitar el token de acceso por primera vez sin nonce 
async function getTokens(nonce) {
  const response = await fetch('https://[TENANT]/oauth/token', {
      method: 'POST',
      body: new URLSearchParams({
        grant_type: '...',
        client_id: '...',
        // Otros parámetros del cuerpo aquí
      }),
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        dpop: generateDPoPHeader('POST', 'https://[TENANT]/oauth/token', nonce),
      }
    });

  const result = await response.json();
  return { response, result };
}

// La primera vez que solicitamos tokens no tendremos un nonce
let { response, result } = await getTokens(); 
console.log('Initial token request result:', result);

if (response.status === 400 && result.error === 'use_dpop_nonce') {
  const nonce = response.headers.get('dpop-nonce');

  console.log('Received nonce:', nonce);

  // Reintentar con el nonce
  ({ response, result } = await getTokens(nonce)); 

  console.log('Tokens received:', result);
}
```

<div id="step-4-auth0-authorization-server-validates-the-dpop-proof-jwt">
  ## Paso 4: El Servidor de autorización de Auth0 valida el JWT de prueba de DPoP
</div>

Cuando el Servidor de autorización de Auth0 recibe la solicitud de token, hace lo siguiente:

* Extrae el JWT de prueba de DPoP, su clave pública y la firma.
* Verifica la firma con la clave pública proporcionada.
* Valida los claim `htm`, `htu`, `jti,` e `iat`.
* Si es válido, emite un token de acceso. El Servidor de autorización de Auth0 incluye un claim de confirmación, `cnf`, en el token de acceso. El claim `cnf` contiene la huella digital (hash) de la clave pública extraída del JWT de prueba de DPoP. Al incluirlo en el token de acceso, el Servidor de autorización de Auth0 vincula el token de acceso a esa clave pública concreta, es decir, restringe su uso al poseedor de esa clave.
* Establece `token_type` en el encabezado `Authorization` como `DPoP` en lugar de `Bearer` en la respuesta del token. Tradicionalmente, cuando el token de acceso se envía en el encabezado `Authorization`, se establece como `Bearer`. Sin embargo, como aquí se envía un token de acceso vinculado a una clave pública mediante DPoP, se establece como `DPoP`.
* A continuación, el Servidor de autorización de Auth0 emite el token de acceso restringido al remitente mediante DPoP para tu aplicación cliente.

<div id="step-5-client-application-calls-api-with-the-dpop-bound-token-and-dpop-proof-jwt">
  ## Paso 5: La aplicación cliente llama a la API con el token vinculado a DPoP y el JWT de prueba de DPoP
</div>

Para cada llamada a la API a un servidor de recursos que aplique DPoP, su aplicación cliente debe presentar tanto el token de acceso vinculado a DPoP como un nuevo JWT de prueba de DPoP.

Al exigir un JWT de prueba de DPoP con cada solicitud a la API, DPoP garantiza que solo la aplicación cliente que posee la clave privada pueda usar el token de acceso.

Para una nueva solicitud a la API, la aplicación cliente:

1. Genera un nuevo JWT de prueba de DPoP con los siguientes claim:

* El claim `htm` es el método `HTTP` de la solicitud a la API, como `GET` o `POST`.
* El claim `htu` es el URI de la solicitud a la API.
* El claim `ath` es el hash SHA-256 codificado en base64url del token de acceso vinculado a DPoP que recibió en el [Paso 3](#step-3-client-application-requests-a-dpop-bound-token).

2. Firma criptográficamente el nuevo JWT de prueba de DPoP con la clave privada del cliente.

3. Incluye el token de acceso vinculado a DPoP en el encabezado `Authorization` mediante el esquema de autenticación `DPoP`:

```javascript lines theme={null}
// El esquema DPoP coincide con el token_type recibido del Servidor de autorización
Authorization: DPoP {access_token}
```

4. Incluye el JWT de prueba de DPoP recién generado en el encabezado HTTP `DPoP`:

```http lines theme={null}
DPoP: {new_dpop_proof_jwt}
```

El encabezado HTTP `DPoP` debe incluir un claim `ath` adicional. El claim `ath` es un hash SHA256 del token de acceso emitido, codificado en base64url.

El servidor de recursos:

* Recibe la solicitud a la API y extrae el token de acceso, la prueba JWT de DPoP, la clave pública y la firma.
* Verifica la firma de la prueba JWT de DPoP con la clave pública de su encabezado `jwk`.
* Valida los claim `htm`, `htu`, `jti`, `iat` y `ath`.
* Verifica que la clave pública indicada en la prueba JWT de DPoP a través de su encabezado `jwk` coincida con la clave pública asociada al token de acceso mediante el claim `cnf.jkt` del token de acceso.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  El servidor de recursos es responsable de implementar la protección contra reproducción de `jti`; no todos los SDK de Auth0 aplican la protección contra reproducción de `jti` de forma predeterminada.
</Callout>

Si todas las comprobaciones son correctas, el servidor de recursos autoriza la solicitud. De lo contrario, rechaza la solicitud y se deniega el acceso.

El siguiente ejemplo de código solicita un token de acceso a Auth0 mediante DPoP y luego llama al endpoint `/userinfo` con un token de acceso vinculado a DPoP:

```jsx lines expandable theme={null}
import { generateKeyPairSync, randomBytes, createHash } from 'node:crypto';
import jwt from 'jsonwebtoken';

const keyPair = generateKeyPairSync('ec', {
  namedCurve: 'P-256',
});

function hashToken(token) {
  return createHash('sha256').update(token).digest('base64url');
}

function generateDPoPHeader(method, url, nonce, accessToken) {
  const jti = randomBytes(16).toString('base64url');
  const jwk = keyPair.publicKey.export({ format: 'jwk' });
  return jwt.sign({
      jti,
      htm: method,
      htu: url,
      iat: Date.now() / 1000,
      nonce,

      // Opcionalmente, incluir un claim `ath` con el hash del token de acceso
      ...(accessToken ? { ath: hashToken(accessToken) } : {}),
    },
    keyPair.privateKey,
    {
      algorithm: 'ES256',
      header: {
        typ: 'dpop+jwt',
        jwk,
      },
    });
  }

async function getTokens(nonce) {
  const response = await fetch('https://[TENANT]/oauth/token', {
      method: 'POST',
      body: new URLSearchParams({
        grant_type: '...',
        client_id: '...',
        // Otros parámetros del cuerpo aquí
      }),
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        dpop: generateDPoPHeader('POST', 'https://test1.local.dev.auth0.com/oauth/token', nonce),
      }
    });

  const result = await response.json();
  return { response, result };
}

// La primera vez que se ejecuta esto, no habrá un nonce disponible
let { response, result } = await getTokens(); 
console.log('Initial token request result:', result);

if (response.status === 400 && result.error === 'use_dpop_nonce') {
  const nonce = response.headers.get('dpop-nonce');
  console.log('Received nonce:', nonce);
  ({ response, result } = await getTokens(nonce)); // Reintentar con el nonce
  console.log('Tokens received:', result);
}

// Llamar a /userinfo con DPoP
const userInfoResponse = await fetch('https://[TENANT]/userinfo', {
  method: 'GET',
  headers: {
    // Enviar el token de acceso usando el esquema de autorización DPoP
    Authorization: `DPoP ${result.access_token}`,

    // Incluir un encabezado DPoP, esta vez con el hash del token de acceso
    dpop: generateDPoPHeader('GET', 'https://[TENANT]/userinfo', nonce, result.access_token),
  },
});

console.log('User info response status:', userInfoResponse.status);
console.log('User info result:', await userInfoResponse.json());
```

<div id="step-6-handle-token-refresh-with-dpop">
  ## Paso 6: Gestionar la renovación de tokens con DPoP
</div>

Cuando tu token de acceso vinculado a DPoP caduque, puedes usar un <Tooltip tip="Token de actualización: Token usado para obtener un nuevo Token de acceso sin obligar a los usuarios a volver a iniciar sesión." cta="Ver glosario" href="/es/docs/glossary?term=refresh+token">token de actualización</Tooltip> para obtener uno nuevo. Una solicitud de token de actualización requiere un JWT de prueba de DPoP generado con el mismo par de claves usado en la solicitud de token original.

A continuación se describe el flujo de actualización de token con DPoP en Auth0:

La aplicación cliente:

* Realiza una solicitud de token de actualización al endpoint `/token` del Servidor de autorización de Auth0.
* Genera un JWT de prueba de DPoP para la solicitud de token de actualización (similar al [Paso 2](#step-2-client-application-creates-a-dpop-proof-jwt), con `htm` como `POST` y `htu` como el URI del <Tooltip tip="Token endpoint: Endpoint del Servidor de autorización que se usa para solicitar tokens mediante programación." cta="Ver glosario" href="/es/docs/glossary?term=token+endpoint">endpoint de token</Tooltip>).
* Incluye el JWT de prueba de DPoP en el encabezado HTTP `DPoP`.

El Servidor de autorización de Auth0:

* Valida el JWT de prueba de DPoP (como en el [Paso 4](#step-4-auth0-authorization-server-validates-the-dpop-proof-jwt)) y emite un nuevo token de acceso vinculado a DPoP.

<div id="important-considerations">
  ## Consideraciones importantes
</div>

Al implementar DPoP en sus aplicaciones cliente, tenga en cuenta lo siguiente:

* **Seguridad de la clave privada:** La seguridad de su implementación de DPoP depende de la seguridad de la clave privada de su cliente, por lo que debe protegerla del acceso no autorizado. Las claves privadas deben generarse y almacenarse en un medio con respaldo de hardware y marcarse como no exportables.
* **Protección contra ataques de repetición (**`jti`\*\* y **`dpop-nonce`**):\*\* El claim `jti` del JWT de prueba de DPoP ayuda a prevenir ataques de repetición en recursos protegidos, como el endpoint [`/userinfo`](https://auth0.com/docs/api/authentication/user-profile/get-user-info). El Servidor de autorización de Auth0 emite un encabezado HTTP `DPoP-Nonce` en la respuesta, que los clientes públicos deben incluir como claim `nonce` en los JWT de prueba de DPoP posteriores para reforzar la protección contra ataques de repetición.
* **Límites de frecuencia:** Como el flujo de desafío-respuesta de DPoP a veces puede requerir una solicitud inicial seguida de un reintento con el nonce proporcionado por el servidor, cada intercambio cuenta en la práctica como dos solicitudes para los [límites de frecuencia de su tenant de Auth0](https://auth0.com/docs/troubleshoot/customer-support/operational-policies/rate-limit-policy). Asegúrese de que el volumen de solicitudes de su aplicación contemple esta sobrecarga.
* **Manejo de errores:** Usted es responsable de implementar la lógica para manejar errores específicos de DPoP del Servidor de autorización de Auth0 o del servidor de recursos, como `invalid_dpop_proof` o `use_dpop_nonce`.
* **Tipos de cliente:** Use DPoP para clientes públicos, como Single Page Applications (SPA) o aplicaciones móviles que no pueden almacenar de forma segura un Secreto del cliente. Para <Tooltip tip="Cliente confidencial: un cliente (aplicación) que puede almacenar credenciales de forma segura mediante un servidor backend de confianza. Algunos ejemplos son una aplicación web con un backend seguro y una aplicación Machine-to-Machine (M2M)." cta="Ver glosario" href="/es/docs/glossary?term=confidential+clients">clientes confidenciales</Tooltip>, como los servicios backend con secretos del cliente, DPoP añade una capa adicional de seguridad, pero ya cuentan con otros mecanismos para restringir el remitente.
* **Rendimiento:** Dado que generar y firmar JWT de prueba de DPoP para cada llamada a la API añade una pequeña sobrecarga, asegúrese de que las operaciones criptográficas de su aplicación cliente sean eficientes.
* **Rotación de claves:** Implemente una estrategia para rotar sus pares de claves de DPoP y así mejorar la seguridad. Asegúrese de usar el mismo par de claves durante la misma sesión.
* **Persistencia:** En las aplicaciones cliente que necesitan mantener una sesión y reutilizar tokens de acceso vinculados a DPoP, como las SPA de larga duración, conserve y recupere de forma segura el par de claves original entre recargas de la aplicación. Si se genera un nuevo par de claves o se usa uno diferente, el token de acceso vinculado a DPoP deja de ser válido, ya que está vinculado criptográficamente a la clave pública del par original. Puede conservar el par de claves, por ejemplo, en `IndexedDB` del navegador o en el almacenamiento seguro de una aplicación móvil.

<div id="learn-more">
  ## Más información
</div>

* [Configurar la restricción del remitente](/es/docs/secure/sender-constraining/configure-sender-constraining)
