> ## 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 llamar a tu propia API desde aplicaciones web tradicionales mediante el Flujo de código de autorización.

# Llama a tu API mediante el Flujo de código de autorización

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

export const codeExample1 = `https://{yourDomain}/authorize?
    response_type=code&
    client_id={yourClientId}&
    redirect_uri={https://yourApp/callback}&
    scope={scope}&
    audience={apiAudience}&
    state={state}`;

export const codeExample2 = `<a href="https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}&  
  scope=appointments%20contacts&
  audience=appointments:api&
  state=xyzABC123">
  Iniciar sesión
</a>`;

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Este tutorial le ayudará a invocar su propia API mediante el Flujo de código de autorización. Si desea obtener más información sobre cómo funciona este flujo y por qué debería usarlo, consulte [Flujo de código de autorización](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow). Si desea aprender a agregar Login a su aplicación web tradicional, consulte [Agregar Login mediante el Flujo de código de autorización](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow).
</Callout>

Auth0 facilita la implementación del Flujo de <Tooltip tip="Código de autorización: Cadena aleatoria generada por el servidor de autorización y devuelta a la aplicación como parte de la respuesta de autorización al usar el Flujo de código de autorización (ya sea con o sin PKCE)." cta="Ver glosario" href="/es/docs/glossary?term=Authorization+Code">código de autorización</Tooltip> en su aplicación mediante:

* [Quickstarts para aplicaciones web tradicionales](/es/docs/quickstart/webapp): La forma más sencilla de implementar el flujo.
* [Authentication API](https://auth0.com/docs/api/authentication): Si prefiere crear su propia solución, siga leyendo para aprender a invocar nuestra API directamente.

<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 **Regular Web Apps** como **Application Type**.
  * Agregue `{https://yourApp/callback}` como **Allowed Callback URL**.
  * Asegúrese de que **Grant Types** de su aplicación incluya **código de autorización**. Para saber cómo hacerlo, consulte [Update Grant Types](/es/docs/get-started/applications/update-grant-types).
  * Si quiere que su aplicación pueda usar [tokens de actualización](/es/docs/secure/tokens/refresh-tokens), asegúrese de que **Grant Types** de la aplicación incluya **refresh token**. Para saber cómo hacerlo, consulte [Update Grant Types](/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 quiere que su API reciba tokens de actualización para poder obtener tokens nuevos cuando caduquen los anteriores, habilite **Allow Offline Access**.

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

<AccordionGroup>
  <Accordion icon="circle-1" title="Autoriza al usuario">
    Este paso puede incluir uno o más de los siguientes procesos:

    * Autenticar al usuario
    * Redirigir al usuario a un Proveedor de identidad para gestionar la autenticación
    * Comprobar si hay sesiones activas de inicio de sesión único (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 enviar al usuario a la [URL de autorización](https://auth0.com/docs/api/authentication#authorization-code-grant).

    #### Ejemplo de URL de autorización

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

    ##### Parámetros

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

    * incluir un parámetro `audience`
    * puedes 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 ser `code`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
    | `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 `code` de la URL. Debes especificar esta URL como una URL de devolución de llamada 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 y *no* respeta ningún fragmento.                                                                                                                                                                                                                                                                                                                                                                                                                |
    | `scope`              | Especifica los [alcances](/es/docs/get-started/apis/scopes) para los que quieres solicitar autorización, que determinan qué claims (o atributos de 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 web quiere acceder. Usa el valor de **Identifier** en la pestaña [Configuración](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 añade a la solicitud inicial y que Auth0 incluye al redirigir de vuelta a tu aplicación. Para ver cómo usar este valor para prevenir ataques de Cross-site Request Forgery (CSRF), consulta [Mitigate CSRF Attacks With State Parameters](/es/docs/secure/attack-protection/state-parameters).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
    | `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 inicio de sesión a tu aplicación podría verse así:

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

    #### Respuesta

    Si todo sale bien, recibirás una respuesta `HTTP 302`. El código de autorización se incluye al final de la URL:

    ```http lines theme={null}
    HTTP/1.1 302 Found
    Location: {https://yourApp/callback}?code={authorizationCode}&state=xyzABC123
    ```
  </Accordion>

  <Accordion icon="circle-2" title="Solicita tokens">
    Ahora que tienes un código de autorización, debes intercambiarlo por tokens. Con el código de autorización (`code`) obtenido en el paso anterior, deberás hacer un `POST` a la [URL de token](https://auth0.com/docs/api/authentication#authorization-code).

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

    ##### Parámetros

    | Nombre del parámetro | Descripción                                                                                                                                                                                                                                                                                                                                                   |
    | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `grant_type`         | Establece este valor en `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 su aplicación. Puede 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, consulte [Credenciales de la aplicación](/es/docs/secure/application-credentials). |
    | `redirect_uri`       | La URL de devolución de llamada válida configurada en la configuración de la aplicación. Debe coincidir exactamente con el valor de `redirect_uri` enviado a la URL de autorización en el paso anterior de este tutorial. Tenga en cuenta que debe estar codificado como URL.                                                                                 |

    #### Respuesta

    Si todo va bien, recibirás una respuesta `HTTP 200` con una carga útil que contiene 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>
      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>

    Los [ID Token](/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 utilizan para llamar al [endpoint /userinfo de la API de autenticación de Auth0](https://auth0.com/docs/api/authentication#get-user-info) u otra API. Si estás llamando a tu propia API, lo primero que esta 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 utilizan para obtener un nuevo token de acceso o token de ID una vez que el anterior ha expirado. El `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 siga autenticado prácticamente de forma indefinida.
    </Warning>
  </Accordion>

  <Accordion icon="circle-3" title="Haz una llamada a la API">
    Para llamar a su API desde una aplicación web tradicional, 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>
  </Accordion>

  <Accordion icon="circle-4" title="Canjear el token de actualización">
    Ya has recibido un [token de actualización](/es/docs/secure/tokens/refresh-tokens) si has seguido este tutorial y completado los siguientes pasos:

    * configurado la API para permitir el acceso sin conexión
    * incluiste 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).

    Puedes usar el Token de actualización para obtener un nuevo token de acceso. Por lo general, un usuario necesitará un nuevo token de acceso solo después de que el anterior haya expirado o al acceder a un nuevo recurso por primera vez. Llamar al endpoint para obtener un nuevo token de acceso cada vez que se llama a una API es una mala práctica; Auth0 aplica límites de frecuencia que restringen la cantidad de solicitudes al endpoint que se pueden ejecutar usando el mismo token desde la misma IP.

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

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

    ###### Parámetros

    | Nombre del parámetro | Descripción                                                                                                                                                                                                                                           |
    | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `grant_type`         | Configura este valor como `refresh_token`.                                                                                                                                                                                                            |
    | `client_id`          | El ID de cliente de su aplicación. Puede 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 separada 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. |

    ###### Respuesta

    Si todo va 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 el `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, lea [Validar ID Tokens](/es/docs/secure/tokens/id-tokens/validate-id-tokens) y [Validar tokens de acceso](/es/docs/secure/tokens/access-tokens/validate-access-tokens).
    </Warning>
  </Accordion>
</AccordionGroup>

<div id="sample-use-cases">
  ### Ejemplos de casos de uso
</div>

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

Puede usar Auth0 Actions para modificar los alcances de 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> y/o agregar claims personalizados a los tokens de acceso y <Tooltip tip="ID Token: credencial destinada al propio cliente, en lugar de para acceder a un recurso." cta="Ver glosario" href="/es/docs/glossary?term=ID+tokens">ID Token</Tooltip>. Para obtener más información sobre Actions, consulte [Comprenda cómo funcionan las Actions de Auth0.](/es/docs/customize/actions/actions-overview)

Para ello, agregue la siguiente Action de Post-Login, que se ejecutará después de que el usuario se autentique:

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

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

<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 claim personalizados agregados a los ID Token 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 colisiones.
</Warning>

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

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