> ## 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 agregar Login a su aplicación nativa, móvil o de página única mediante el Flujo de código de autorización con Proof Key for Code Exchange (PKCE).

# Agregar Login mediante el Flujo de código de autorización con PKCE

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

Puede agregar Login a su aplicación nativa, móvil o de una sola página mediante el Flujo de código de autorización con PKCE. Para obtener información sobre cómo funciona el flujo y por qué debería usarlo, lea [Flujo de código de autorización con Proof Key for Code Exchange (PKCE)](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce). Para obtener información sobre cómo llamar a su API desde una aplicación nativa, móvil o de una sola página, lea [Llame a su API mediante el Flujo de código de autorización con PKCE](/es/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce/call-your-api-using-the-authorization-code-flow-with-pkce).

Para implementar el Flujo de código de autorización con Proof Key for Code Exchange (PKCE), puede usar los siguientes recursos:

* [SDK móviles de Auth0](/es/docs/libraries) y [SDK de aplicaciones de una sola página de Auth0](/es/docs/libraries/auth0-single-page-app-sdk): La forma más sencilla de implementar el flujo, ya que se encargan de casi todo por usted. Nuestros [Quickstarts para móviles](/es/docs/quickstart/native) y [Quickstarts para aplicaciones de una sola página](/es/docs/quickstart/spa) le guiarán en el proceso.
* [Authentication API](https://auth0.com/docs/api/authentication): Si prefiere crear su propia solución, siga leyendo para aprender a llamar a nuestra API directamente.

Después de iniciar sesión correctamente, su aplicación tendrá acceso al <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+token">token de ID</Tooltip> y al <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=access+token">token de acceso</Tooltip> del usuario. El token de ID contendrá información básica del perfil de usuario, y el token de acceso puede usarse para llamar al endpoint `/userinfo` de Auth0 o a sus propias API protegidas. Para obtener más información sobre los tokens de ID, lea [ID Tokens](/es/docs/secure/tokens/id-tokens). Para obtener más información sobre los tokens de acceso, lea [Access Tokens](/es/docs/secure/tokens/access-tokens).

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

Registra tu aplicación con Auth0. Para obtener más información, consulta [Registrar aplicaciones nativas](/es/docs/get-started/auth0-overview/create-applications/native-apps) o [Registrar aplicaciones web de una sola página](/es/docs/get-started/auth0-overview/create-applications/single-page-web-apps).

* Selecciona **Native** o **Single-Page App** como **Tipo de aplicación**, según corresponda a tu aplicación.
* Agrega `YOUR_CALLBACK_URL` como **URL de devolución de llamada permitida**. El formato de la URL de devolución de llamada variará según el tipo de aplicación y la plataforma. Para obtener más información sobre el formato correspondiente a tu tipo de aplicación y plataforma, consulta nuestros [Quickstarts de Native/Mobile](/es/docs/quickstart/native) y [Quickstarts para aplicaciones de una sola página](/es/docs/quickstart/spa).
* Asegúrate de que los **Tipos de concesión** de tu aplicación incluyan **Código de autorización**. Para obtener más información, consulta [Actualizar tipos de concesión](/es/docs/get-started/applications/update-grant-types).

<div id="create-code-verifier">
  ## Crear un verificador de código
</div>

Cree un `code_verifier`, que es una clave aleatoria generada criptográficamente y codificada en Base64, que posteriormente se enviará a Auth0 para solicitar tokens.

Para obtener más información sobre el algoritmo para crear el `code_verifier`, lea la sección [4.1 El cliente crea un verificador de código](https://datatracker.ietf.org/doc/html/rfc7636#section-4.1) de la especificación <Tooltip tip="OAuth 2.0: Marco de autorización que define protocolos y flujos de autorización." cta="Ver glosario" href="/es/docs/glossary?term=OAuth">OAuth</Tooltip> Proof Key for Code Exchange.

<div id="javascript-sample">
  ### Ejemplo de JavaScript
</div>

```javascript lines theme={null}
// Dependencia: módulo crypto de Node.js
// https://nodejs.org/api/crypto.html#crypto_crypto
function base64URLEncode(str) {
    return str.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}
var verifier = base64URLEncode(crypto.randomBytes(32));
```

<div id="java-sample">
  ### Ejemplo de Java
</div>

```javascript lines theme={null}
// Dependencia: Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/
// Importar la clase Base64.
// import org.apache.commons.codec.binary.Base64;
SecureRandom sr = new SecureRandom();
byte[] code = new byte[32];
sr.nextBytes(code);
String verifier = Base64.getUrlEncoder().withoutPadding().encodeToString(code);
```

<div id="android-sample">
  ### Ejemplo para Android
</div>

```javascript lines theme={null}
// Dependencia: Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/
// Importar la clase Base64.
// import org.apache.commons.codec.binary.Base64;
SecureRandom sr = new SecureRandom();
byte[] code = new byte[32];
sr.nextBytes(code);
String verifier = Base64.encodeToString(code, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
```

<div id="swift-5-sample">
  ### Ejemplo en Swift 5
</div>

```javascript lines theme={null}
var buffer = [UInt8](repeating: 0, count: 32)
_ = SecRandomCopyBytes(kSecRandomDefault, buffer.count, &buffer)
let verifier = Data(buffer).base64EncodedString()
    .replacingOccurrences(of: "+", with: "-")
    .replacingOccurrences(of: "/", with: "_")
    .replacingOccurrences(of: "=", with: "")
```

<div id="objective-c-sample">
  ### Ejemplo en Objective-C
</div>

```objc lines theme={null}
NSMutableData *data = [NSMutableData dataWithLength:32];
int result __attribute__((unused)) = SecRandomCopyBytes(kSecRandomDefault, 32, data.mutableBytes);
NSString *verifier = [[[[data base64EncodedStringWithOptions:0]
                        stringByReplacingOccurrencesOfString:@"+" withString:@"-"]
                        stringByReplacingOccurrencesOfString:@"/" withString:@"_"]
                        stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]];
```

<div id="create-code-challenge">
  ## Crear un desafío de código
</div>

Genera un `code_challenge` a partir del `code_verifier`, que se enviará a Auth0 para solicitar un `authorization_code`.

Para obtener más información sobre cómo se deriva el `code_challenge` del `code_verifier`, consulta la sección [4.2 Client Creates the Code Challenge](https://datatracker.ietf.org/doc/html/rfc7636#section-4.) de la especificación OAuth Proof Key for Code Exchange.

<div id="javascript-sample">
  ### Ejemplo de JavaScript
</div>

```javascript lines theme={null}
// Dependencia: módulo crypto de Node.js
// https://nodejs.org/api/crypto.html#crypto_crypto
function sha256(buffer) {
    return crypto.createHash('sha256').update(buffer).digest();
}
var challenge = base64URLEncode(sha256(verifier));
```

### Ejemplo en Java

```java lines theme={null}
// Dependencia: Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/
// Importar la clase Base64.
// import org.apache.commons.codec.binary.Base64;
byte[] bytes = verifier.getBytes("US-ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bytes, 0, bytes.length);
byte[] digest = md.digest();
String challenge = Base64.encodeBase64URLSafeString(digest);
```

### Ejemplo de Swift 5

```swift lines theme={null}
import CommonCrypto

// ...

guard let data = verifier.data(using: .utf8) else { return nil }
var buffer = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
_ = data.withUnsafeBytes {
    CC_SHA256($0.baseAddress, CC_LONG(data.count), &buffer)
}
let hash = Data(buffer)
let challenge = hash.base64EncodedString()
    .replacingOccurrences(of: "+", with: "-")
    .replacingOccurrences(of: "/", with: "_")
    .replacingOccurrences(of: "=", with: "")
```

<div id="objective-c-sample">
  ### Ejemplo en Objective-C
</div>

```objc lines theme={null}
// Dependencia: biblioteca Apple Common Crypto
// http://opensource.apple.com//source/CommonCrypto
u_int8_t buffer[CC_SHA256_DIGEST_LENGTH * sizeof(u_int8_t)];
memset(buffer, 0x0, CC_SHA256_DIGEST_LENGTH);
NSData *data = [verifier dataUsingEncoding:NSUTF8StringEncoding];
CC_SHA256([data bytes], (CC_LONG)[data length], buffer);
NSData *hash = [NSData dataWithBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
NSString *challenge = [[[[hash base64EncodedStringWithOptions:0]
                         stringByReplacingOccurrencesOfString:@"+" withString:@"-"]
                         stringByReplacingOccurrencesOfString:@"/" withString:@"_"]
                         stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]];
```

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

Solicita la autorización del usuario y redirígelo de nuevo a tu aplicación con un `authorization_code`.

Una vez que hayas creado el `code_verifier` y el `code_challenge`, debes obtener la autorización del usuario. Técnicamente, este es el comienzo del <Tooltip tip="Flujo de autorización: concesión de autorización (o flujo de trabajo) especificado en el marco de OAuth 2.0." cta="Ver glosario" href="/es/docs/glossary?term=authorization+flow">flujo de autorización</Tooltip>, y 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 administra identidades digitales." cta="Ver glosario" href="/es/docs/glossary?term=Identity+Provider">Proveedor de identidad</Tooltip> para gestionar la autenticación;
* Comprobar si hay sesiones activas de [inicio de sesión único (SSO)](/es/docs/authenticate/single-sign-on);
* Obtener el consentimiento del usuario para el nivel de permisos solicitado, a menos que ya lo 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-pkce-), incluyendo el `code_challenge` que generaste en el paso anterior y el método que utilizaste para generarlo.

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

export const codeExample1 = `https://{yourDomain}/authorize?
    response_type=code&
    code_challenge={codeChallenge}&
    code_challenge_method=S256&
    client_id={yourClientId}&
    redirect_uri={yourCallbackUrl}&
    scope={scope}&
    state={state}`;

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

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

| 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`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `code_challenge`        | Desafío generado a partir del `code_verifier`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `code_challenge_method` | Método utilizado para generar el desafío (por ejemplo, S256). La especificación de PKCE define dos métodos, `S256` y `plain`; el primero se usa en este ejemplo y es el **único** compatible con Auth0, ya que el segundo no se recomienda.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `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).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `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`. Debe 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 de 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 desea solicitar autorización, que determinan qué claim (o atributos del usuario) desea recibir. Deben estar separados por espacios. Para obtener un ID Token en la respuesta, debe especificar al menos el scope `openid`. Si desea recibir el perfil completo del usuario, puede solicitar `openid profile`. Puede solicitar cualquiera de los [scopes estándar de OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) sobre usuarios, como `email`, o [claim personalizado](/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). Incluya `offline_access` para obtener un [Token de actualización](/es/docs/glossary?term=Refresh+Token) (asegúrese de que el campo **Allow Offline Access** esté habilitado en la [configuración de la aplicación](https://manage.auth0.com/#/applications)). |
| `state`                 | (recomendado) Una cadena alfanumérica arbitraria y opaca que su aplicación agrega a la solicitud inicial y que Auth0 incluye al redirigir de vuelta a su aplicación. Para ver cómo usar este valor para evitar ataques de falsificación de solicitudes entre sitios (CSRF), consulte [Mitigate CSRF Attacks With State Parameters](/es/docs/secure/attack-protection/state-parameters).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `connection`            | (opcional) Obliga al usuario a iniciar sesión con una conexión específica. Por ejemplo, puede pasar un valor de `github` para enviar al usuario directamente a GitHub e iniciar sesión con su cuenta de GitHub. Cuando no se especifica, el usuario verá la pantalla de Auth0 Lock con todas las conexiones configuradas. Puede ver una lista de sus conexiones configuradas en la pestaña **Connections** de su aplicación.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `organization`          | (opcional) ID de la organización que se usará al autenticar a un usuario. Cuando no se proporciona, si su 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), su aplicación debe gestionar la aceptación de la invitación reenviando los pares clave-valor `invitation` y `organization` cuando el usuario la acepte.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

Como ejemplo, el fragmento HTML de su URL de autorización al agregar login a su aplicación podría verse así:

export const codeExample2 = `<a href="https://{yourDomain}/authorize?
  response_type=code&
  code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&
  code_challenge_method=S256&
  client_id={yourClientId}&
  redirect_uri={yourCallbackUrl}&
  scope=openid%20profile&
  state=xyzABC123">
  Iniciar sesión
</a>`;

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

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

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: {yourCallbackUrl}?code={authorizationCode}&state=xyzABC123
```

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

Intercambia tu `authorization_code` y `code_verifier` por tokens.

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

<div id="post-to-token-url-example">
  ### 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=authorization_code \
    --data 'client_id={yourClientId}' \
    --data 'code_verifier={yourGeneratedCodeVerifier}' \
    --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}&code_verifier=%7ByourGeneratedCodeVerifier%7D&code=%7ByourAuthorizationCode%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}&code_verifier=%7ByourGeneratedCodeVerifier%7D&code=%7ByourAuthorizationCode%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}&code_verifier=%7ByourGeneratedCodeVerifier%7D&code=%7ByourAuthorizationCode%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}',
      code_verifier: '{yourGeneratedCodeVerifier}',
      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}&code_verifier=%7ByourGeneratedCodeVerifier%7D&code=%7ByourAuthorizationCode%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}&code_verifier=%7ByourGeneratedCodeVerifier%7D&code=%7ByourAuthorizationCode%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}&code_verifier=%7ByourGeneratedCodeVerifier%7D&code=%7ByourAuthorizationCode%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`         | Establécelo en "authorization\_code".                                                                                                                                                                                                                              |
| `code_verifier`      | La clave criptográficamente aleatoria que se generó en el primer paso de este tutorial.                                                                                                                                                                            |
| `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).                                                                                           |
| `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 `redirect_uri` enviado a la URL de autorización en el paso anterior de este tutorial. Ten en cuenta que debe estar codificada como URL. |

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

Si todo sale 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",
  "expires_in":86400
}
```

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

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

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

[Tokens de actualización](/es/docs/secure/tokens/refresh-tokens) se usan para obtener un nuevo token de acceso o token de ID después de que el anterior haya expirado. `refresh_token` solo estará presente en la respuesta si incluyó el scope `offline_access` y habilitó **Allow Offline Access** para su 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="use-cases">
  ## Casos de uso
</div>

<div id="basic-authentication-request">
  ### Solicitud de autenticación básica
</div>

Este ejemplo muestra la solicitud más básica que puede realizar para autorizar al usuario en el paso 1. Muestra la pantalla de Login de Auth0 y permite que el usuario inicie sesión con cualquiera de las conexiones que tenga configuradas:

export const codeExample13 = `https://{yourDomain}/authorize?
    response_type=code&
    code_challenge={codeChallenge}&
    code_challenge_method=S256&
    client_id={yourClientId}&
    redirect_uri={yourCallbackUrl}&
    scope=openid`;

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

Ahora, cuando solicites tokens, tu ID Token contendrá los claims más básicos. Cuando decodifiques el ID Token, tendrá un aspecto similar a:

```json lines theme={null}
{
  "iss": "https://auth0pnp.auth0.com/",
  "sub": "auth0|581...",
  "aud": "xvt9...",
  "exp": 1478112929,
  "iat": 1478076929
}
```

<div id="request-users-name-and-profile-picture">
  ### Solicitar el nombre y la foto de perfil del usuario
</div>

Además de la autenticación habitual del usuario, este ejemplo muestra cómo solicitar datos adicionales del usuario, como su nombre y su foto de perfil.

Para solicitar el nombre y la foto de perfil del usuario, debes agregar los alcances adecuados al autorizar al usuario:

export const codeExample14 = `https://{yourDomain}/authorize?
    response_type=code&
    code_challenge={codeChallenge}&
    code_challenge_method=S256&
    client_id={yourClientId}&
    redirect_uri={yourCallbackUrl}&
    scope=openid%20name%20picture&
    state={state}`;

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

Ahora, cuando solicites tokens, tu token de ID contendrá los claims de nombre e imagen solicitados. Cuando decodifiques el token de ID, tendrá un aspecto similar a:

```json lines theme={null}
{
  "name": "auth0user@...",
  "picture": "https://example.com/profile-pic.png",
  "iss": "https://auth0user.auth0.com/",
  "sub": "auth0|581...",
  "aud": "xvt...",
  "exp": 1478113129,
  "iat": 1478077129
}
```

<div id="request-user-log-in-with-github">
  ### Solicitar el inicio de sesión de usuarios con GitHub
</div>

Además de la autenticación habitual de usuarios, este ejemplo muestra cómo enviar a los usuarios directamente a un Proveedor de identidad social, como GitHub. Para que este ejemplo funcione, debe ir a [Auth0 Dashboard > Authentication > Social](https://manage.auth0.com/#/connections/social) y configurar la conexión correspondiente. Obtenga el nombre de la conexión en la pestaña **Settings**.

Para enviar a los usuarios directamente a la pantalla de inicio de sesión de GitHub, debe pasar el parámetro `connection` y establecer su valor en el nombre de la conexión (en este caso, `github`) al autorizar al usuario:

export const codeExample15 = `https://{yourDomain}/authorize?
    response_type=code&
    code_challenge={codeChallenge}&
    code_challenge_method=S256&
    client_id={yourClientId}&
    redirect_uri={yourCallbackUrl}&
    scope=openid%20name%20picture&
    state={state}&
    connection=github`;

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

Ahora, cuando solicites tokens, tu token de ID contendrá un claim `sub` con el id único del usuario que devuelve GitHub. Cuando decodifiques el token de ID, se verá de forma similar a:

```json lines theme={null}
{
  "name": "John Smith",
  "picture": "https://avatars.example.com",
  "email": "jsmith@...",
  "email_verified": true,
  "iss": "https://auth0user.auth0.com/",
  "sub": "github|100...",
  "aud": "xvt...",
  "exp": 1478114742,
  "iat": 1478078742
}
```

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

* [Marco 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)
