> ## 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.

> Aprenda a ejecutar el flujo híbrido para que su aplicación pueda usar un token de ID para acceder a la información del usuario y, al mismo tiempo, obtener un código de autorización que pueda intercambiarse por un Token de acceso.

# Llame a su API con el flujo híbrido

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

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

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Este tutorial le ayudará a llamar a su propia API con el Flujo híbrido. Si desea obtener más información sobre cómo funciona este flujo y por qué debería usarlo, consulte [Flujo híbrido](/es/docs/get-started/authentication-and-authorization-flow/hybrid-flow).
</Callout>

Auth0 facilita que su aplicación implemente el Flujo de código de autorización mediante:

* [Authentication API](https://auth0.com/docs/api/authentication): Si prefiere crear su propia solución, siga leyendo para aprender a llamar directamente a nuestra API.

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

**Antes de comenzar este tutorial:**

* [Registre su aplicación en Auth0](/es/docs/get-started/auth0-overview/create-applications/regular-web-apps).

  * Seleccione el **Tipo de aplicación** adecuado.
  * Agregue una **URL de callback permitida**: `{https://yourApp/callback}`.
  * Asegúrese de que los **Tipos de concesión** de su aplicación incluyan **Implícito** y **Código de autorización**. Para saber cómo hacerlo, consulte [Actualizar tipos de concesión](/es/docs/get-started/applications/update-grant-types).
  * Si desea que su aplicación pueda usar Tokens de actualización, asegúrese de que los **Tipos de concesión** de la aplicación incluyan **Token de actualización**. Para saber cómo hacerlo, consulte [Actualizar tipos de concesión](/es/docs/get-started/applications/update-grant-types). Para obtener más información sobre los Tokens de actualización, consulte [Tokens de actualización](/es/docs/secure/tokens/refresh-tokens).
* [Registre su API en Auth0](/es/docs/get-started/auth0-overview/set-up-apis)

  * Si desea que su API reciba Tokens de actualización para poder obtener tokens nuevos cuando caduquen los anteriores, habilite **Permitir acceso sin conexión**.

<div id="steps">
  ## Pasos
</div>

1. [Autorizar al usuario](#authorize-user):
   Solicite autorización al usuario y rediríjalo de vuelta a su aplicación con un código de autorización.
2. [Solicitar tokens](#request-tokens):
   Intercambie su código de autorización por tokens.
3. [Llamar a la API](#call-api):
   Use el Token de acceso obtenido para llamar a su API.
4. [Renovar tokens](#refresh-tokens):
   Use un Token de actualización para solicitar tokens nuevos cuando los actuales expiren.

Opcional: [Explorar casos de uso de muestra](#sample-use-cases)

<div id="authorize-user">
  ### Autorizar al usuario
</div>

Este paso puede incluir uno o más de los siguientes procesos:

* Autenticar al usuario
* Redirigir al usuario a un <Tooltip tip="Proveedor de identidad (IdP): servicio que almacena y gestiona identidades digitales." cta="Ver glosario" href="/es/docs/glossary?term=Identity+Provider">Proveedor de identidad</Tooltip> para gestionar la autenticación
* Comprobar si existen sesiones activas de <Tooltip tip="Inicio de sesión único (SSO): servicio que, después de que un usuario inicia sesión en una aplicación, inicia automáticamente su sesión en otras aplicaciones." cta="Ver glosario" href="/es/docs/glossary?term=Single+Sign-on">inicio de sesión único</Tooltip> (SSO)
* Obtener el consentimiento del usuario para el nivel de permisos solicitado, a menos que ya se haya otorgado previamente.

Para autorizar al usuario, tu aplicación debe dirigirlo a la [URL de autorización](https://auth0.com/docs/api/authentication#authorization-code-grant).

<div id="example-authorization-url">
  #### Ejemplo de URL de autorización
</div>

export const codeExample1 = `https://{yourDomain}/authorize?
    response_type=YOUR_RESPONSE_TYPE&
    response_mode=form_post&
    client_id={yourClientId}&
    redirect_uri={https://yourApp/callback}&
    scope=SCOPE&
    audience=API_AUDIENCE&
    state=STATE&
    nonce=NONCE`;

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

<div id="parameters">
  ##### Parámetros
</div>

Ten en cuenta que, para autorizar a un usuario al llamar a una API personalizada, debes:

* incluir un parámetro <Tooltip tip="Audiencia: identificador único de la audiencia de un token emitido. Se denomina aud en un token; su valor contiene el ID de una aplicación (ID de cliente) para un ID Token o de una API (Identificador de API) para un token de acceso." cta="Ver glosario" href="/es/docs/glossary?term=audience">audience</Tooltip>
* incluir alcances adicionales compatibles con la API de destino

| Nombre del parámetro | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `response_type`      | Indica el tipo de credencial que devolverá Auth0 (code o token). Para este flujo, el valor debe incluir `code`, pero también puede incluir `id_token`, `token` o `id_token token`. En concreto, `id_token` devuelve un ID Token y `token` devuelve un Token de acceso.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `response_mode`      | Especifica el método con el que deben devolverse los parámetros de respuesta. Por motivos de seguridad, el valor debe ser `form_post`. En este modo, los parámetros de respuesta se codificarán como valores de formulario HTML que se transmiten mediante el método HTTP POST y se codifican en el cuerpo con el formato `application/x-www-form-urlencoded`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `client_id`          | El ID de cliente de tu aplicación. Puedes encontrar este valor en la [configuración de la aplicación](https://manage.auth0.com/#/Applications/\{yourClientId}/settings).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `redirect_uri`       | La URL a la que Auth0 redirigirá el navegador después de que el usuario haya concedido la autorización. El código de autorización estará disponible en el parámetro de URL `code`. Debes especificar esta URL como una URL de callback válida en la [configuración de la aplicación](https://manage.auth0.com/#/Applications/\{yourClientId}/settings).<br /><br />**Advertencia:** Según la [especificación OAuth 2.0](https://tools.ietf.org/html/rfc6749#section-3.1.2), Auth0 elimina todo lo que aparece después del hash e *ignora* cualquier fragmento.                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scope`              | Especifica los [alcances](/es/docs/get-started/apis/scopes) para los que quieres solicitar autorización, que determinan qué claims (o atributos del usuario) quieres que se devuelvan. Deben separarse con un espacio. Puedes solicitar cualquiera de los [alcances estándar de OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) sobre usuarios, como `profile` o `email`, [claims personalizados](/es/docs/secure/tokens/json-web-tokens/json-web-token-claims#custom-claims) que cumplan con un [formato con espacio de nombres](/es/docs/secure/tokens/json-web-tokens/create-custom-claims), o cualquier alcance compatible con la API de destino (por ejemplo, `read:contacts`). Incluye `offline_access` para obtener un [Token de actualización](/es/docs/glossary?term=Refresh+Token) (asegúrate de que el campo **Allow Offline Access** esté habilitado en la [configuración de la aplicación](https://manage.auth0.com/#/applications)). |
| `audience`           | El identificador único de la API a la que tu aplicación quiere acceder. Usa el valor de **Identifier** en la pestaña [Settings](https://manage.auth0.com/#/apis) de la API que creaste como parte de los requisitos previos de este tutorial.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `state`              | (recomendado) Una cadena alfanumérica arbitraria y opaca que tu aplicación agrega a la solicitud inicial y que Auth0 incluye al redirigir de vuelta a tu aplicación. Para ver cómo usar este valor para evitar ataques de falsificación de solicitudes entre sitios (CSRF), consulta [Mitigate CSRF Attacks With State Parameters](/es/docs/secure/attack-protection/state-parameters).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `nonce`              | Una cadena aleatoria criptográficamente segura que tu aplicación agrega a la solicitud inicial y que Auth0 incluye dentro del ID Token, [utilizada para evitar ataques de repetición de tokens](/es/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post/mitigate-replay-attacks-when-using-the-implicit-flow).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `organization`       | (opcional) ID de la organización que se usará al autenticar a un usuario. Si no se proporciona, y tu aplicación está configurada para **Display Organization Prompt**, el usuario podrá introducir el nombre de la organización al autenticarse.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `invitation`         | (opcional) ID del ticket de invitación de la organización. Al [invitar a un miembro a una Organización](/es/docs/manage-users/organizations/configure-organizations/invite-members), tu aplicación debe gestionar la aceptación de la invitación reenviando los pares clave-valor `invitation` y `organization` cuando el usuario acepte la invitación.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

Como ejemplo, tu fragmento HTML para la URL de autorización al agregar el inicio de sesión a tu aplicación podría verse así:

export const codeExample2 = `<a href="https://{yourDomain}/authorize?
  response_type=code id_token token&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}&  
  scope=appointments%20contacts&
  audience=appointments:api&
  state=xyzABC123&
  nonce=eq...hPmz">
  Sign In
</a>`;

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

<div id="response">
  #### Respuesta
</div>

Si todo sale bien, recibirá una respuesta `HTTP 302`. Las credenciales solicitadas están codificadas en el cuerpo:

```json lines theme={null}
HTTP/1.1 302 Found
Content-Type: application/x-www-form-urlencoded
code=AUTHORIZATION_CODE&
access_token=ey...MhPw
&expires_in=7200
&token_type=Bearer
id_token=eyJ...acA&
state=xyzABC123
```

Tenga en cuenta que los valores devueltos dependen de lo que haya solicitado como `response_type`.

| Tipo de respuesta | Componentes                                                             |
| ----------------- | ----------------------------------------------------------------------- |
| `code `           | Código de autorización                                                  |
| `id_token `       | ID Token                                                                |
| `token `          | Token de acceso (más los valores `expires_in` y `token_type`)           |
| `id_token token`  | ID Token, Token de acceso (más los valores `expires_in` y `token_type`) |

Auth0 también devolverá cualquier valor de `state` que haya incluido en su llamada a la URL de autorización.

<Warning>
  El Token de acceso que recibe en esta transacción es solo el primero que recibirá. No recomendamos usarlo para llamar a APIs.
</Warning>

<Warning>
  Valide sus tokens antes de guardarlos. Para saber cómo hacerlo, lea [Validar tokens de ID](/es/docs/secure/tokens/id-tokens/validate-id-tokens) y [Validar tokens de acceso](/es/docs/secure/tokens/access-tokens/validate-access-tokens).
</Warning>

Cuando decodifique y analice su <Tooltip tip="ID Token: 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>, observará un claim adicional, `c_hash`, que contiene un hash del `code`. Este claim es obligatorio cuando se emite un token de ID al mismo tiempo que un `code`, y debe validarlo:

1. Con el algoritmo hash especificado en el claim `alg` del encabezado del ID Token, calcule el hash de los octetos de la representación ASCII del `code`.
2. Codifique en Base64url la mitad izquierda del hash.
3. Compruebe que el resultado coincida con el valor de `c_hash`.

<div id="request-tokens">
  ### Solicitar tokens
</div>

Ahora que tiene un código de autorización, debe canjearlo por tokens. Con el código de autorización extraído (`code`) en el paso anterior, deberá enviar una solicitud `POST` a la [URL del token](https://auth0.com/docs/api/authentication#authorization-code).

El <Tooltip tip="Token de acceso: credencial de autorización, en forma de una cadena opaca o JWT, que se usa para acceder a una API." cta="Ver glosario" href="/es/docs/glossary?term=Access+Token">token de acceso</Tooltip> que reciba en este paso es el que debe usar para llamar a su API. Asegúrese de mantenerlo separado del token de acceso que recibió en el paso anterior de este tutorial.

#### Ejemplo de POST a la URL del token

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=authorization_code \
    --data 'client_id={yourClientId}' \
    --data 'client_secret={yourClientSecret}' \
    --data 'code=yourAuthorizationCode}' \
    --data 'redirect_uri={https://yourApp/callback}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "grant_type=authorization_code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&code=yourAuthorizationCode%7D&redirect_uri={https://yourApp/callback}", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/token"

  	payload := strings.NewReader("grant_type=authorization_code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&code=yourAuthorizationCode%7D&redirect_uri={https://yourApp/callback}")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("content-type", "application/x-www-form-urlencoded")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=authorization_code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&code=yourAuthorizationCode%7D&redirect_uri={https://yourApp/callback}")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      code: 'yourAuthorizationCode}',
      redirect_uri: '{https://yourApp/callback}'
    })
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=authorization_code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&code=yourAuthorizationCode%7D&redirect_uri={https://yourApp/callback}",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=authorization_code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&code=yourAuthorizationCode%7D&redirect_uri={https://yourApp/callback}"

  headers = { 'content-type': "application/x-www-form-urlencoded" }

  conn.request("POST", "/{yourDomain}/oauth/token", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/token")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/x-www-form-urlencoded'
  request.body = "grant_type=authorization_code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&code=yourAuthorizationCode%7D&redirect_uri={https://yourApp/callback}"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="parameters">
  ##### Parámetros
</div>

| Nombre del parámetro | Descripción                                                                                                                                                                                                                                                                                                                                                    |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`         | Configura este valor como `authorization_code`.                                                                                                                                                                                                                                                                                                                |
| `code`               | El `authorization_code` obtenido en el paso anterior de este tutorial.                                                                                                                                                                                                                                                                                         |
| `client_id`          | El ID de cliente de tu aplicación. Puedes encontrar este valor en la [configuración de la aplicación](https://manage.auth0.com/#/Applications/\{yourClientId}/settings).                                                                                                                                                                                       |
| `client_secret`      | El Secreto del cliente de tu aplicación. Puedes encontrar este valor en la [configuración de la aplicación](https://manage.auth0.com/#/Applications/\{yourClientId}/settings). Para obtener más información sobre los métodos de autenticación de aplicaciones disponibles, consulta [Credenciales de la aplicación](/es/docs/secure/application-credentials). |
| `redirect_uri`       | La URL de callback válida configurada en la configuración de la aplicación. Debe coincidir exactamente con el valor de `redirect_uri` que se pasó a la URL de autorización en el paso anterior de este tutorial. Ten en cuenta que debe estar codificada en formato URL.                                                                                       |

<div id="response">
  #### Respuesta
</div>

Si todo va bien, recibirás una respuesta `HTTP 200` con una carga útil que incluye los valores `access_token`, `refresh_token`, `id_token` y `token_type`:

```json lines theme={null}
{
  "access_token": "eyJz93a...k4laUWw",
  "refresh_token": "GEbRxBN...edjnXbL",
  "id_token": "eyJ0XAi...4faeEoQ",
  "token_type": "Bearer"
}
```

<Warning>
  Valida tus tokens antes de guardarlos. Para saber cómo hacerlo, consulta [Validar tokens de ID](/es/docs/secure/tokens/id-tokens/validate-id-tokens) y [Validar tokens de acceso](/es/docs/secure/tokens/access-tokens/validate-access-tokens).
</Warning>

[Los tokens de ID](/es/docs/secure/tokens/id-tokens) contienen información del usuario que debe decodificarse y extraerse.

[Los tokens de acceso](/es/docs/secure/tokens/access-tokens) se usan para llamar al [endpoint /userinfo de la Authentication API de Auth0](https://auth0.com/docs/api/authentication#get-user-info) o a otra API. Si llamas a tu propia API, lo primero que deberá hacer es [verificar el token de acceso](/es/docs/secure/tokens/access-tokens/validate-access-tokens).

[Los tokens de actualización](/es/docs/secure/tokens/refresh-tokens) se usan para obtener un nuevo token de acceso o token de ID una vez que el anterior haya expirado. `refresh_token` solo estará presente en la respuesta si incluiste el scope `offline_access` y habilitaste **Allow Offline Access** para tu API en el Dashboard.

<Warning>
  Los tokens de actualización deben almacenarse de forma segura, ya que permiten que un usuario permanezca autenticado prácticamente de forma indefinida.
</Warning>

<div id="call-api">
  ### Llamar a la API
</div>

Para llamar a su API desde una aplicación web estándar (o en casos similares en los que las credenciales de la aplicación pueden almacenarse de forma segura), la aplicación debe enviar el Token de acceso obtenido como Bearer Token en el encabezado Authorization de la solicitud HTTP.

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url https://myapi.com/api \
    --header 'authorization: Bearer {accessToken}' \
    --header 'content-type: application/json'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://myapi.com/api");
  var request = new RestRequest(Method.GET);
  request.AddHeader("content-type", "application/json");
  request.AddHeader("authorization", "Bearer {accessToken}");
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines expandable theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://myapi.com/api"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("content-type", "application/json")
  	req.Header.Add("authorization", "Bearer {accessToken}")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines theme={null}
  HttpResponse response = Unirest.get("https://myapi.com/api")
    .header("content-type", "application/json")
    .header("authorization", "Bearer {accessToken}")
    .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://myapi.com/api',
    headers: {'content-type': 'application/json', authorization: 'Bearer {accessToken}'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP lines expandable theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://myapi.com/api",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {accessToken}",
      "content-type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("myapi.com")

  headers = {
      'content-type': "application/json",
      'authorization': "Bearer {accessToken}"
      }

  conn.request("GET", "/api", headers=headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://myapi.com/api")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)
  request["content-type"] = 'application/json'
  request["authorization"] = 'Bearer {accessToken}'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="refresh-tokens">
  ### Tokens de actualización
</div>

Ya recibió un [token de actualización](/es/docs/secure/tokens/refresh-tokens) si ha estado siguiendo este tutorial y completó lo siguiente:

* configuró su API para permitir acceso sin conexión
* incluyó el scope `offline_access` al iniciar la solicitud de autenticación a través del [endpoint de autorización](https://auth0.com/docs/api/authentication/reference#authorize-application).

Puede usar el <Tooltip tip="Token de actualización: token que se usa para obtener un nuevo Token de acceso sin obligar a los usuarios a iniciar sesión de nuevo." cta="Ver glosario" href="/es/docs/glossary?term=Refresh+Token">Token de actualización</Tooltip> para obtener un nuevo token de acceso. Normalmente, un usuario solo necesitará un nuevo token de acceso después de que caduque el anterior o cuando obtenga acceso a un nuevo recurso por primera vez. Es una mala práctica llamar al endpoint para obtener un nuevo token de acceso cada vez que llame a una API, y Auth0 aplica límites de tasa que restringen la cantidad de solicitudes al endpoint que pueden ejecutarse con el mismo token desde la misma IP.

Para actualizar su token, haga una solicitud `POST` al endpoint `/oauth/token` de la Authentication API con `grant_type=refresh_token`.

<div id="example-post-to-token-url">
  #### Ejemplo de solicitud POST a la URL del token
</div>

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=refresh_token \
    --data 'client_id={yourClientId}' \
    --data 'refresh_token={yourRefreshToken}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "grant_type=refresh_token&client_id={yourClientId}&refresh_token=%7ByourRefreshToken%7D", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/token"

  	payload := strings.NewReader("grant_type=refresh_token&client_id={yourClientId}&refresh_token=%7ByourRefreshToken%7D")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("content-type", "application/x-www-form-urlencoded")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=refresh_token&client_id={yourClientId}&refresh_token=%7ByourRefreshToken%7D")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: '{yourClientId}',
      refresh_token: '{yourRefreshToken}'
    })
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=refresh_token&client_id={yourClientId}&refresh_token=%7ByourRefreshToken%7D",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=refresh_token&client_id={yourClientId}&refresh_token=%7ByourRefreshToken%7D"

  headers = { 'content-type': "application/x-www-form-urlencoded" }

  conn.request("POST", "/{yourDomain}/oauth/token", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/token")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/x-www-form-urlencoded'
  request.body = "grant_type=refresh_token&client_id={yourClientId}&refresh_token=%7ByourRefreshToken%7D"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="parameters">
  ##### Parámetros
</div>

| Nombre del parámetro | Descripción                                                                                                                                                                                                                                                |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`         | Establece este valor en `refresh_token`.                                                                                                                                                                                                                   |
| `client_id`          | El ID de cliente de tu aplicación. Puedes encontrar este valor en la [configuración de la aplicación](https://manage.auth0.com/#/Applications/\{yourClientId}/settings).                                                                                   |
| `refresh_token`      | El token de actualización que se va a usar.                                                                                                                                                                                                                |
| `scope`              | (opcional) Una lista de permisos de `scope` solicitados, delimitada por espacios. Si no se envía, se usarán los alcances originales; de lo contrario, puedes solicitar un conjunto reducido de alcances. Ten en cuenta que debe estar codificado para URL. |

<div id="response">
  #### Respuesta
</div>

Si todo sale bien, recibirás una respuesta `HTTP 200` con una carga útil que contiene un nuevo `access_token`, su duración en segundos (`expires_in`), los valores de `scope` otorgados y `token_type`. Si el scope del token inicial incluía `openid`, la respuesta también incluirá un nuevo `id_token`:

```json lines theme={null}
{
  "access_token": "eyJ...MoQ",
  "expires_in": 86400,
  "scope": "openid offline_access",
  "id_token": "eyJ...0NE",
  "token_type": "Bearer"
}
```

<Warning>
  Valide sus tokens antes de guardarlos. Para saber cómo hacerlo, consulte [Validar tokens de ID](/es/docs/secure/tokens/id-tokens/validate-id-tokens) y [Validar tokens de acceso](/es/docs/secure/tokens/access-tokens/validate-access-tokens).
</Warning>

<div id="sample-use-cases">
  ### Casos de uso de ejemplo
</div>

<div id="customize-tokens">
  #### Personalizar tokens
</div>

Puede usar Rules para cambiar los alcances que se devuelven en los tokens de acceso y/o agregar claims a los tokens de acceso y a los ID Tokens. (Para obtener más información sobre Rules, consulte [Auth0 Rules](/es/docs/customize/rules).) Para ello, agregue la siguiente Rule, que se ejecutará después de que el usuario se autentique:

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  // Agregar claims personalizados al Token de acceso y al ID Token
  api.accessToken.setCustomClaim('https://foo/bar', 'value');
  api.idToken.setCustomClaim('https://fiz/baz', 'some other value');

  // Modificar el scope del Token de acceso
  api.accessToken.addScope('foo');
  api.accessToken.addScope('bar');
};
```

Los alcances estarán disponibles en el token una vez que se hayan ejecutado todas las Rules.

<Warning>
  Auth0 devuelve la información del perfil en un formato estructurado de claims, tal como lo define la [especificación OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). Esto significa que los claims personalizados agregados a los ID tokens o a los tokens de acceso deben [ajustarse a las directrices y restricciones](/es/docs/secure/tokens/json-web-tokens/create-custom-claims) para evitar posibles conflictos.
</Warning>

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

* [Framework de autorización de OAuth 2.0](/es/docs/authenticate/protocols/oauth)
* [Protocolo OpenID Connect](/es/docs/authenticate/protocols/openid-connect-protocol)
* [Tokens](/es/docs/secure/tokens)
