> ## 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 alcances y claims con aplicaciones y API.

# Casos prácticos: alcances y claims

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****ENMASCARADO*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

export const codeExample1 = `https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}&
  scope=openid%20profile%20email&
  state=YOUR_STATE_VALUE
`;

export const codeExample2 = `{
  "name": "John Doe",
  "nickname": "john.doe",
  "picture": "https://myawesomeavatar.com/avatar.png",
  "updated_at": "2017-03-30T15:13:40.474Z",
  "email": "john.doe@test.com",
  "email_verified": false,
  "iss": "https://{yourDomain}/",
  "sub": "auth0|USER-ID",
  "aud": "{yourClientId}",
  "exp": 1490922820,
  "iat": 1490886820,
  "nonce": "crypto-value",
  "at_hash": "IoS3ZGppJKUn3Bta_LgE2A"
}`;

export const codeExample3 = `https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}& 
  scope=read:appointments&
  audience=YOUR_API_AUDIENCE&
  state=YOUR_STATE_VALUE
`;

export const codeExample4 = `https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}& 
  scope=openid%20profile%20email%20read:appointments&
  audience=YOUR_API_AUDIENCE&
  state=YOUR_STATE_VALUE
`;

En estos ejemplos, usamos el [Flujo de código de autorización](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow) para autenticar a un usuario y solicitar los permisos (alcances) y los tokens necesarios. Para obtener más información sobre los parámetros de la solicitud o aprender a implementar este flujo por completo, consulta nuestro tutorial: [Agregar inicio de sesión a aplicaciones web tradicionales](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow).

<div id="authenticate-a-user-and-request-standard-claims">
  ## Autentique a un usuario y solicite claims estándar
</div>

En este ejemplo, queremos autenticar a un usuario y obtener datos del usuario que nos permitan personalizar nuestra interfaz de usuario. Para ello, necesitamos obtener un <Tooltip tip="token de ID: credencial destinada al propio cliente, en lugar de usarse para acceder a un recurso." cta="Ver glosario" href="/es/docs/glossary?term=ID+token">token de ID</Tooltip> que contenga la información del nombre, alias, foto de perfil y correo electrónico del usuario.

1. Inicie el flujo de autenticación enviando al usuario a la URL de autorización:

   <AuthCodeBlock children={codeExample1} language="text" />

   Tenga en cuenta que, en este ejemplo:

   * El parámetro `response_type` incluye un valor:

     * `code`: como estamos usando el flujo de aplicación web tradicional, nuestra solicitud inicial es para un código de autorización; cuando solicitemos los tokens con este código, recibiremos el token de ID que necesitamos para la autenticación.
   * El parámetro `scope` incluye tres valores: los alcances de OIDC solicitados.

     * `openid`: para indicar que la aplicación pretende usar OIDC para verificar la identidad del usuario.
     * `profile`: para obtener `name`, `nickname` y `picture`.
     * `email`: para obtener `email` y `email_verified`.
2. Después de que el usuario otorgue su consentimiento (si es necesario) y Auth0 redirija a su aplicación, [solicite los tokens](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow).
3. Extraiga el token de ID de la respuesta y [decodifíquelo](/es/docs/secure/tokens/id-tokens). Debería ver los siguientes claims:

   <AuthCodeBlock children={codeExample2} language="json" />

   Su aplicación ahora puede recuperar los atributos del usuario y usarlos para personalizar su interfaz de usuario.

<div id="request-custom-api-access">
  ## Solicitar acceso a una API personalizada
</div>

En este ejemplo, solicitamos un scope personalizado para una API de calendario que autorizará a la aplicación que la consume a leer las citas del usuario. Para ello, queremos obtener un <Tooltip tip="Token de acceso: credencial de autorización, en forma de una cadena opaca o JWT, utilizada para acceder a una API." cta="Ver glosario" href="/es/docs/glossary?term=access+token">token de acceso</Tooltip> que contenga el scope adecuado para leer citas de la API. Ten en cuenta que solicitar un token de acceso no depende de solicitar un token de ID.

Antes de usar una API personalizada, debes saber qué alcances están disponibles para la API a la que llamas. Si la API personalizada está bajo tu control, debes registrar tanto tu aplicación como la API en Auth0 y [definir los alcances de tu API en Auth0 Dashboard](/es/docs/get-started/apis/scopes/api-scopes). También puedes usar permisos definidos para [personalizar la pantalla de consentimiento](/es/docs/customize/login-pages/customize-consent-prompts) para tus usuarios.

1. Inicia el flujo de autorización enviando al usuario a la URL de autorización:

   <AuthCodeBlock children={codeExample3} language="text" />

   Observa que en este ejemplo:

   * El parámetro `response_type` sigue incluyendo un valor:

     * `code`: como estamos usando el flujo habitual para aplicaciones web, nuestra solicitud inicial es para un código de autorización; cuando solicitemos nuestros tokens con este código, recibiremos el Token de acceso que podremos usar para llamar a nuestra API.
   * el parámetro `scope` incluye un valor: el scope de API solicitado:

     * `read:appointments`: para permitirnos leer las citas del usuario desde la API.
   * El parámetro `audience` es nuevo e incluye un valor:

     * El identificador único de la API de la que queremos leer las citas del usuario.
2. Como en el ejemplo anterior, después de que el usuario otorgue su consentimiento (si es necesario) y Auth0 redirija de vuelta a tu aplicación, [solicita los tokens](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow).
3. Extrae el token de acceso de la respuesta y llama a la API usando el token de acceso como credencial.

<div id="authenticate-a-user-and-request-standard-claims-and-custom-api-access">
  ## Autentique a un usuario y solicite claims estándar y acceso a una API personalizada
</div>

En este ejemplo, combinamos los dos ejemplos anteriores para autenticar a un usuario, solicitar claims estándar y también solicitar un scope personalizado para una API de calendario que permita a la aplicación que realiza la llamada leer las citas del usuario. Para ello, obtenga dos tokens:

* token de ID que contiene:

  * nombre del usuario
  * apodo
  * imagen de perfil
  * información del correo electrónico
* token de acceso que contiene el scope adecuado para leer citas desde la API. Tenga en cuenta que solicitar un token de acceso no depende de solicitar un token de ID.

Antes de usar una API personalizada, necesita saber qué alcances están disponibles para la API a la que llama. Si la API personalizada está bajo su control, debe registrar tanto su aplicación como la API en Auth0 y [definir los alcances de su API con Auth0 Dashboard](/es/docs/get-started/apis/scopes/api-scopes). También puede usar permisos definidos para [personalizar la pantalla de consentimiento](/es/docs/customize/login-pages/customize-consent-prompts) para sus usuarios.

1. Inicie el flujo de autenticación enviando al usuario a la URL de autorización:

   <AuthCodeBlock children={codeExample4} language="text" />

   Tenga en cuenta que, en este ejemplo:

   * El parámetro `response_type` sigue incluyendo un valor:

     * `code`: como estamos usando el flujo para aplicaciones web tradicionales, nuestra solicitud inicial es para un código de autorización; cuando solicitemos los tokens con este código, recibiremos tanto el token de ID que necesitamos para la autenticación como el token de acceso que podemos usar para llamar a nuestra API.
   * El parámetro `scope` se usa tanto para alcances de OIDC como para alcances de API, por lo que ahora incluye cuatro valores:

     * `openid`: para indicar que la aplicación tiene previsto usar OIDC para verificar la identidad del usuario.
     * `profile`: para obtener `name`, `nickname` y `picture`.
     * `email`: para obtener `email` y `email_verified`.
     * `read:appointments`: para permitirnos leer las citas del usuario desde la API.
   * El parámetro `audience` incluye un valor:

     * El identificador único de la API desde la que queremos leer las citas del usuario
2. Como en los ejemplos anteriores, después de que el usuario otorgue su consentimiento (si es necesario) y Auth0 lo redirija de vuelta a su aplicación, solicite los tokens.
3. Extraiga el token de ID de la respuesta, descodifíquelo, recupere los atributos del usuario y úselos para personalizar su interfaz de usuario.
4. Extraiga el token de acceso de la respuesta y llame a la API usando el token de acceso como credencial.

<div id="add-custom-claims-to-a-token">
  ## Agregar claims personalizadas a un token
</div>

En este ejemplo, agregamos el color favorito y el método de contacto preferido de un usuario al token de ID. Para ello, creamos una [Action](/es/docs/customize/actions) para personalizar el token de ID agregando estas [claims](/es/docs/secure/tokens/json-web-tokens/create-custom-claims). Una vez agregadas, también podremos obtener las claims personalizadas al llamar al endpoint `/userinfo` (aunque la Action solo se ejecutará durante el proceso de autenticación).

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Auth0 permite claims con espacio de nombres y sin espacio de nombres, pero se aplican ciertas restricciones (consulta [Restricciones generales](/es/docs/secure/tokens/json-web-tokens/create-custom-claims#general-restrictions)). Para evitar colisiones de nombres, recomendamos usar claims con espacio de nombres. En caso de colisión, la transacción no fallará, pero tu claim personalizada no se añadirá a tus tokens.
</Callout>

Supongamos que:

* En algún momento, el usuario seleccionó un método `preferred_contact` de `email` y un `favorite_color` de `red`, y los guardamos como parte del `user_metadata` del usuario.
* Hemos usado la [Management API](https://auth0.com/docs/api/management/v2#!/Users/patch_users_by_id) o el Dashboard para establecer información específica de la aplicación para este usuario.

En este caso, el [perfil de usuario normalizado](/es/docs/manage-users/user-accounts/user-profiles/normalized-user-profiles) almacenado en Auth0 es:

```json lines theme={null}
{
  "email": "jane@example.com",
  "email_verified": true,
  "user_id": "custom|123",
  "favorite_color": "blue",
  "user_metadata": {
    "preferred_contact": "email"
  }
}
```

Para este perfil, Auth0 normalmente devolvería a su aplicación los siguientes claims del token de ID:

```json lines theme={null}
{
  "email": "jane@example.com",
  "email_verified": true,
  "iss": "https://my-domain.auth0.com/",
  "sub": "custom|123",
  "aud": "my_client_id",
  "iat": 1311280970,
  "exp": 1311281970
}
```

Ten en cuenta que en este ejemplo:

* El claim `sub` contiene el valor de la propiedad `user_id`.
* Ni la propiedad `favorite_color` ni la propiedad `user_metadata` aparecen porque <Tooltip tip="OpenID: estándar abierto de autenticación que permite a las aplicaciones verificar la identidad de los usuarios sin recopilar ni almacenar información de inicio de sesión." cta="Ver glosario" href="/es/docs/glossary?term=OpenID">OpenID</Tooltip> Connect (OIDC) no define claims estándar que representen `favorite_color` o `user_metadata`.

Para recibir los datos personalizados, tendremos que [crear una nueva Action](/es/docs/customize/actions/write-your-first-action) para personalizar el token con [claims personalizados](/es/docs/secure/tokens/json-web-tokens/create-custom-claims) que representen estas propiedades del perfil del usuario.

1. Ve a [Auth0 Dashboard > Actions > Library](https://manage.auth0.com/#/actions/library) y selecciona **Build Custom**.

2. Introduce un **Nombre** descriptivo para tu Action (por ejemplo, `Add user metadata to tokens`), selecciona el desencadenador `Login / Post Login` porque vas a añadir la Action al flujo de inicio de sesión y, a continuación, selecciona **Create**.

3. Busca el editor de código de Actions, copia en él el siguiente código JavaScript y selecciona **Save Draft** para guardar los cambios:

   ```javascript lines theme={null}
   exports.onExecutePostLogin = async (event, api) => {
     const namespace = 'https://myapp.example.com';
     const { favorite_color, preferred_contact } = event.user.user_metadata;

     if (event.authorization) {
       // Set claims 
       api.idToken.setCustomClaim(`${namespace}/favorite_color`, favorite_color);
       api.idToken.setCustomClaim(`${namespace}/preferred_contact`, preferred_contact);
     }
   };
   ```

4. En la barra lateral del editor de código de Actions, selecciona Test (icono de reproducción) y, después, selecciona **Run** para [probar tu código](/es/docs/customize/actions/test-actions).

5. Cuando tengas lista la Action para ponerla en producción, selecciona **Deploy**.

Por último, añade la Action que has creado al [Login Flow](https://manage.auth0.com/#/actions/flows/login/). Para obtener información sobre cómo adjuntar Actions a los Flows, consulta la sección "Attach the Action to a flow" en [Write Your First Action](/es/docs/customize/actions/write-your-first-action).

Con esta Action habilitada, Auth0 incluirá los claims personalizados `favorite_color` y `preferred_contac`t en el token de ID:

```json lines theme={null}
{
  "email": "jane@example.com",
  "email_verified": true,
  "iss": "https://my-domain.auth0.com/",
  "sub": "custom|123",
  "aud": "my_client_id",
  "iat": 1311280970,
  "exp": 1311281970,
  "https://myapp.example.com/favorite_color": "red",
  "https://myapp.example.com/preferred_contact": "email"
}
```

Al crear tu Action, asegúrate de definir una lógica que determine cuándo incluir claims adicionales. Inyectar claims personalizados en cada token de ID emitido no es lo ideal.

Este ejemplo muestra cómo se agregan claims personalizados a un token de ID mediante el método `api.idToken.setCustomClaims`. Para agregar estos claims a un Token de acceso, usa el método `api.accessToken.setCustomClaim`.

Para obtener más información sobre el objeto de evento del trigger, consulta [Actions Triggers: post-login - Event Object](/es/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object). Para obtener más información sobre los tokens, consulta [Tokens](/es/docs/secure/tokens).

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

* [alcances de OpenID Connect](/es/docs/get-started/apis/scopes/openid-connect-scopes)
* [Crear claims personalizados](/es/docs/secure/tokens/json-web-tokens/create-custom-claims)
* [alcances de API](/es/docs/get-started/apis/scopes/api-scopes)
* [Configurar una API lógica para varias APIs](/es/docs/get-started/apis/set-logical-api)
