> ## 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 llamar a su API desde un dispositivo con capacidad de entrada limitada mediante el Flujo de autorización de dispositivo.

# Llame a su API mediante el Flujo de autorización de dispositivo

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 te ayudará a llamar a tu propia API desde un dispositivo con entrada limitada mediante el Flujo de autorización de dispositivo. Si quieres obtener más información sobre cómo funciona el flujo y por qué deberías usarlo, consulta [Flujo de autorización de dispositivo](/es/docs/get-started/authentication-and-authorization-flow/device-authorization-flow).
</Callout>

Auth0 facilita la implementación del flujo de <Tooltip tip="Flujo de autorización: concesión de autorización (o flujo de trabajo) especificada en el marco de OAuth 2.0." cta="Ver glosario" href="/es/docs/glossary?term=Authorization+flow">autorización</Tooltip> de dispositivo en tu aplicación mediante:

* [Authentication API](https://auth0.com/docs/api/authentication): Sigue leyendo para aprender a llamar directamente a nuestra API. Para una experiencia interactiva, consulta [Entorno de pruebas del flujo de dispositivo](https://auth0.github.io/device-flow-playground/).

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

Antes de comenzar este tutorial:

* Consulte las limitaciones (a continuación) para asegurarse de que el Flujo de autorización de dispositivo sea adecuado para su implementación.
* [Registre la aplicación en Auth0](/es/docs/get-started/auth0-overview/create-applications/native-apps).

  * Seleccione **Native** en **Application Type**.
  * Si es necesario, configure **Allowed Web Origins**. Puede usar esta opción para permitir localhost como origen durante el desarrollo local o para establecer un origen permitido para software de TV específico con una arquitectura sujeta a CORS (por ejemplo, HTML5 + JS). La mayoría de las aplicaciones no usarán esta configuración.
  * Asegúrese de que la opción **OIDC Conformant** esté habilitada. Esta configuración se encuentra en el [Dashboard](https://manage.auth0.com/#), en **Applications > Application > Advanced Settings > OAuth**.
  * Asegúrese de que los **Grant Types** de la aplicación incluyan **Device Code**. Para saber cómo hacerlo, consulte [Actualizar tipos de concesión](/es/docs/get-started/applications/update-grant-types).
  * Si desea que la aplicación pueda usar tokens de actualización, asegúrese de que los **Grant Types** de la aplicación incluyan **Refresh Token**. 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).
* Configure y habilite al menos una conexión para la aplicación: [Conexiones de base de datos](/es/docs/get-started/applications/set-up-database-connections), [Conexiones sociales](/es/docs/authenticate/identity-providers/social-identity-providers)
* [Registre su API en Auth0](/es/docs/get-started/architecture-scenarios/mobile-api/part-2#create-the-api)

  * Si desea que su API reciba tokens de actualización para poder obtener nuevos tokens cuando caduquen los anteriores, habilite **Allow Offline Access**. Para obtener más información sobre los tokens de actualización, consulte [Tokens de actualización](/es/docs/secure/tokens/refresh-tokens).
* [Configure los ajustes del código de usuario del dispositivo](/es/docs/get-started/tenant-settings/configure-device-user-code-settings) para definir el conjunto de caracteres, el formato y la longitud de su código de usuario generado aleatoriamente.

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

1. [Solicitar código de dispositivo](#request-device-code) (flujo de dispositivo): Solicite un código de dispositivo que el usuario pueda usar para autorizar el dispositivo.
2. [Solicitar activación del dispositivo](#request-device-activation) (flujo de dispositivo): Solicite que el usuario autorice el dispositivo con su portátil o smartphone.
3. [Solicitar tokens](#request-tokens) (flujo de dispositivo): Consulte periódicamente el endpoint de token para solicitar un token.
4. [Autorizar al usuario](#authorize-user) (flujo del navegador): El usuario autoriza el dispositivo para que este pueda recibir tokens.
5. [Recibir tokens](#receive-tokens) (flujo de dispositivo): Después de que el usuario autorice correctamente el dispositivo, reciba los tokens.
6. [Llamar a la API](#call-your-api) (flujo de dispositivo): Use el Token de acceso obtenido para llamar a su API.
7. [Renovar tokens](#refresh-tokens) (flujo de dispositivo): Use un Token de actualización para solicitar nuevos tokens cuando los existentes expiren.

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

Opcional: [Solucionar problemas](#troubleshoot).

<div id="request-device-code">
  ### Solicitar código de dispositivo
</div>

Una vez que el usuario haya iniciado la aplicación del dispositivo y quiera autorizarlo, deberá obtener un código de dispositivo. Cuando el usuario inicie su sesión en el dispositivo con navegador, este código quedará vinculado a esa sesión.

Para obtener el código de dispositivo, su aplicación debe solicitar un código en la [URL del código de dispositivo](https://auth0.com/docs/api/authentication#get-device-code), incluido el <Tooltip tip="ID de cliente: valor de identificación que Auth0 asigna a su recurso registrado." cta="Ver glosario" href="/es/docs/glossary?term=Client+ID">ID de cliente</Tooltip>.

<div id="example-post-to-device-code-url">
  #### Ejemplo de POST a la URL de código de dispositivo
</div>

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

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/device/code");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%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/device/code"

  	payload := strings.NewReader("client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%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/device/code")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D")
    .asString();
  ```

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

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/device/code',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: {client_id: '{yourClientId}', scope: '{scope}', audience: '{audience}'}
  };

  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/device/code",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%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 = "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D"

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

  conn.request("POST", "/{yourDomain}/oauth/device/code", 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/device/code")

  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 = "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D"

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

<div id="device-code-parameters">
  ##### Parámetros del código de dispositivo
</div>

Ten en cuenta que, al solicitar un código de dispositivo para llamar a una API personalizada:

* debes incluir un parámetro <Tooltip tip="Audiencia: identificador único de la audiencia de un token emitido. En un token se denomina aud; 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>
* puedes incluir alcances adicionales admitidos por la API de destino

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Si tu aplicación solo quiere un Token de acceso para obtener información sobre el usuario autenticado, no se requiere ningún parámetro audience.
</Callout>

| Nombre del parámetro | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scope`              | Los [alcances](/es/docs/get-started/apis/scopes) para los que quieres solicitar autorización. Deben estar separados por espacios. Puedes solicitar cualquiera de los [alcances estándar de OIDC](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) sobre usuarios, como `profile` y `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 admitido por la API de destino](/es/docs/get-started/apis/scopes/api-scopes) (por ejemplo, `read:contacts`). Incluye `openid` para obtener un ID Token o para poder usar el [endpoint /userinfo](https://auth0.com/docs/api/authentication#user-profile) y recuperar información del perfil del usuario. Incluye `offline_access` para obtener un Token de actualización (asegúrate de que el campo **Allow Offline Access** esté habilitado en la [configuración de la API](https://manage.auth0.com/#/apis)). Ten en cuenta que debe estar codificado como URL. |
| `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. Ten en cuenta que debe estar codificado como URL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

<div id="device-code-response">
  #### Respuesta del código de dispositivo
</div>

Si todo sale bien, recibirás una respuesta `HTTP 200` con una carga útil que contiene los valores `device_code`, `user_code`, `verification_uri`, `expires_in`, `interval` y `verification_uri_complete`:

```json lines theme={null}
{
  "device_code": "Ag_EE...ko1p",
  "user_code": "QTZL-MCBW",
  "verification_uri": "https://accounts.acmetest.org/activate",
  "verification_uri_complete": "https://accounts.acmetest.org/activate?user_code=QTZL-MCBW",
  "expires_in": 900,
  "interval": 5
}
```

* `device_code` es el código único del dispositivo. Cuando el usuario acceda a `verification_uri` desde un dispositivo con navegador, este código se vinculará a su sesión.
* `user_code` contiene el código de usuario que debe introducirse en `verification_uri` para autorizar el dispositivo.
* `verification_uri` contiene la URL que el usuario debe visitar para autorizar el dispositivo.
* `verification_uri_complete` contiene la URL completa que el usuario debe visitar para autorizar el dispositivo. Esto permite que su aplicación incorpore `user_code` en la URL, si así lo desea.
* `expires_in` indica la duración (en segundos) de `device_code` y `user_code`.
* `interval` indica el intervalo (en segundos) con el que la aplicación debe consultar la URL del token para solicitar un token.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Puede [configurar el conjunto de caracteres, el formato y la longitud de su código de usuario generado aleatoriamente](/es/docs/get-started/tenant-settings/configure-device-user-code-settings) en la Configuración del Tenant.

  Para evitar ataques de fuerza bruta, aplicamos los siguientes límites a `user_code`:

  **Longitud mínima**:

  * Letras BASE20: 8 caracteres
  * Números: 9 caracteres

  **Longitud máxima**:

  * 20 caracteres (incluidos los guiones y los espacios, que pueden añadirse como separadores para mejorar la legibilidad)

  **Tiempo de expiración**:

  * 15 minutos
</Callout>

<div id="request-device-activation">
  ### Solicitar la activación del dispositivo
</div>

Una vez que hayas recibido un `device_code` y un `user_code`, debes pedirle al usuario que vaya a la `verification_uri` desde su portátil o smartphone e introduzca el `user_code`:

<Frame>
  <img src="https://mintcdn.com/translations/Dcx0M11uuptU53TX/docs/images/cdy7uua7fh8z/2WzaeNXIYCVduRuzyRd0Sb/cdb4d59b657166d0a9a555a662b9ed63/request-device-activation.png?fit=max&auto=format&n=Dcx0M11uuptU53TX&q=85&s=c452a5b19705d03633ccbfa1247e1fc6" alt="Auth0 Flows Device Authorization Request, página de ejemplo que muestra dos métodos de activación: user_code y código QR" width="1986" height="1432" data-path="docs/images/cdy7uua7fh8z/2WzaeNXIYCVduRuzyRd0Sb/cdb4d59b657166d0a9a555a662b9ed63/request-device-activation.png" />
</Frame>

El `device_code` no está pensado para el usuario y no debe mostrarse durante la interacción para evitar confundirlo.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Al crear una CLI, puedes omitir este paso y abrir el navegador directamente con `verification_uri_complete`.
</Callout>

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

Mientras espera a que el usuario active el dispositivo, comience a sondear la URL del token para solicitar 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>. Con el intervalo de sondeo (`interval`) extraído del paso anterior, deberá realizar un `POST` a la [URL del token](https://auth0.com/docs/api/authentication#device-auth) enviando el `device_code`.

Para evitar errores debidos a la latencia de la red, debe comenzar a contar cada intervalo después de recibir la respuesta de la última solicitud de sondeo.

<div id="example-request-token-post-to-token-url">
  #### Ejemplo de solicitud POST de token 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=urn:ietf:params:oauth:grant-type:device_code \
    --data 'device_code={yourDeviceCode}' \
    --data 'client_id={yourClientId}'
  ```

  ```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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}", 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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}")

  	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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}")
    .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: 'urn:ietf:params:oauth:grant-type:device_code',
      device_code: '{yourDeviceCode}',
      client_id: '{yourClientId}'
    })
  };

  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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}",
    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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}"

  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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}"

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

<div id="token-request-parameters">
  ##### Parámetros de la solicitud de token
</div>

| Nombre del parámetro | Descripción                                                                                                                                                                                                                                                 |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`         | Establézcalo en "urn:ietf:params:oauth:grant-type:device\_code". Este es un tipo de concesión de extensión (como se define en la sección 4.5 de [RFC6749](https://tools.ietf.org/html/rfc6749#section-4.5)). Tenga en cuenta que debe codificarse como URL. |
| `device_code`        | El `device_code` recuperado en el paso anterior de este tutorial.                                                                                                                                                                                           |
| `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).                                                                                     |

<div id="token-responses">
  #### Respuestas de token
</div>

Mientras espera a que el usuario autorice el dispositivo, es posible que reciba varias respuestas `HTTP 4xx`:

<div id="authorization-pending">
  ##### Autorización pendiente
</div>

Verá este error mientras espera a que el usuario realice alguna acción. Continúe con el sondeo usando el intervalo sugerido obtenido en el paso anterior de este tutorial.

```json lines theme={null}
HTTP/1.1 403 Forbidden
{
  "error": "authorization_pending",
  "error_description": "..."
}
```

<div id="slow-down">
  ##### Vaya más despacio
</div>

Está realizando el sondeo demasiado rápido. Vaya más despacio y use el intervalo sugerido obtenido en el paso anterior de este tutorial. Para evitar que se produzca este error debido a la latencia de la red, debe empezar a contar cada intervalo después de recibir la respuesta a la última solicitud de sondeo.

```json lines theme={null}
HTTP/1.1 429 Too Many Requests
{
  "error": "slow_down",
  "error_description": "..."
}
```

<div id="expired-token">
  ##### Token vencido
</div>

El usuario no autorizó el dispositivo con la suficiente rapidez, por lo que el `device_code` venció. Su aplicación debe notificarle que el flujo venció e indicarle que lo inicie de nuevo.

<Warning>
  El error `expired_token` se devolverá exactamente una vez; después de eso, se devolverá `invalid_grant`. Su dispositivo **debe** detener el sondeo.
</Warning>

```json lines theme={null}
HTTP/1.1 403 Bad Request
{ 
  "error": "expired_token",
  "error_description": "..."
}
```

<div id="access-denied">
  ##### Acceso denegado
</div>

Por último, si se deniega el acceso, recibirá:

```json lines theme={null}
HTTP/1.1 403 Forbidden
{
  "error": "access_denied",
  "error_description": "..."
}
```

Esto puede ocurrir por diversos motivos, entre ellos:

* el usuario se negó a autorizar el dispositivo
* el <Tooltip tip="Servidor de autorización: servidor centralizado que ayuda a definir los límites del acceso de un usuario. Por ejemplo, tu servidor de autorización puede controlar los datos, las tareas y las funciones disponibles para un usuario." cta="Ver glosario" href="/es/docs/glossary?term=authorization+server">servidor de autorización</Tooltip> denegó la transacción
* una Rule configurada denegó el acceso (Para obtener más información, consulta [Auth0 Rules](/es/docs/customize/rules).)

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

El usuario escaneará el código QR o, de lo contrario, abrirá la página de activación e introducirá el código de usuario:

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7KRZGb2QcksaEVewXK5bc2/b688b813428f0750ea76b7bcac418bba/enter-user-code__1_.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=e814986a9a1eec7cadb6fea50c646497" alt="Pantalla de autorización de dispositivos de Auth0 Flows que indica al usuario que introduzca el code que se muestra en su dispositivo" width="390" height="532" data-path="docs/images/cdy7uua7fh8z/7KRZGb2QcksaEVewXK5bc2/b688b813428f0750ea76b7bcac418bba/enter-user-code__1_.png" />
</Frame>

Se mostrará una página de confirmación para que el usuario confirme que se trata del dispositivo correcto:

<Frame>
  <img src="https://mintcdn.com/translations/MV7tE-x71x8RWRES/docs/images/cdy7uua7fh8z/4udH69PJSo20QyK8cwhhtc/193488ee0f689f0724345a40dcdb6478/confirm-device__1_.png?fit=max&auto=format&n=MV7tE-x71x8RWRES&q=85&s=771499858a79702e1084c6551dab7c3e" alt="Ejemplo de pantalla de confirmación de autorización de dispositivos de Auth0 Flows que indica al usuario que confirme el code" width="394" height="532" data-path="docs/images/cdy7uua7fh8z/4udH69PJSo20QyK8cwhhtc/193488ee0f689f0724345a40dcdb6478/confirm-device__1_.png" />
</Frame>

El usuario completará la transacción iniciando sesión. 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 encargarse de la autenticación;
* Comprobar si hay 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, lo inicia sesión automáticamente en otras aplicaciones." cta="Ver glosario" href="/es/docs/glossary?term=SSO">SSO</Tooltip>;
* Obtener el consentimiento del usuario para el dispositivo, a menos que ya lo haya otorgado previamente.

<Frame>
  <img src="https://mintcdn.com/translations/pvjQqAy3EB2TK6NP/docs/images/cdy7uua7fh8z/4UbIdGQMucMhoaXxvFLcki/8c1616d7f28bbd37c253a0145a93a17d/user-auth__1_.png?fit=max&auto=format&n=pvjQqAy3EB2TK6NP&q=85&s=8338c652e72d813a0dcc386af5a97b21" alt="Pantalla de autorización de usuario para la autorización de dispositivos de Auth0 Flows que indica al usuario que inicie sesión con correo electrónico y contraseña o con Google u otra identidad" width="317" height="584" data-path="docs/images/cdy7uua7fh8z/4UbIdGQMucMhoaXxvFLcki/8c1616d7f28bbd37c253a0145a93a17d/user-auth__1_.png" />
</Frame>

Tras autenticarse correctamente y otorgar el consentimiento, se mostrará la pantalla de confirmación:

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7ze8nZU4b0q3YOzLQSJ6nJ/48ef5170035a200cebb821c581cec9bb/user-confirmation__1_.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=08d4f09c478a98f6d5b745e7e6b3e1a6" alt="Flows - Autorización de dispositivos - Notificación de felicitación para el usuario" width="392" height="536" data-path="docs/images/cdy7uua7fh8z/7ze8nZU4b0q3YOzLQSJ6nJ/48ef5170035a200cebb821c581cec9bb/user-confirmation__1_.png" />
</Frame>

En este punto, el usuario se ha autenticado y el dispositivo ha sido autorizado.

<div id="receive-tokens">
  ### Recibir tokens
</div>

Mientras el usuario se autentica y autoriza el dispositivo, la aplicación del dispositivo sigue consultando la URL del token para solicitar un token de acceso.

Una vez que el usuario haya autorizado correctamente el dispositivo, recibirás una respuesta `HTTP 200` con una carga útil que contiene los valores `access_token`, `refresh_token` (opcionalmente), `id_token` (opcionalmente), `token_type` y `expires_in`:

```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 [Validate ID Tokens](/es/docs/secure/tokens/id-tokens/validate-id-tokens) y [Validate Access Tokens](/es/docs/secure/tokens/access-tokens/validate-access-tokens).
</Warning>

Los tokens de acceso se usan para llamar al [endpoint `/userinfo`](https://auth0.com/docs/api/authentication#get-user-info) de la API de autenticación de Auth0 o a otra API. (Para obtener más información sobre los tokens de acceso, lea [Access Tokens](/es/docs/secure/tokens/access-tokens).) Solo podrá usar el Token de acceso para llamar a `/userinfo` si incluyó el scope `openid`. 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).

<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+Tokens">ID Tokens</Tooltip> contienen información del usuario que debe decodificarse y extraerse. (Para obtener más información sobre los ID Token, lea [ID Tokens](/es/docs/secure/tokens/id-tokens).) El `id_token` solo estará presente en la respuesta si incluyó el scope `openid`.

<Tooltip tip="Token de actualización: Token que se usa para obtener un Token de acceso renovado sin obligar a los usuarios a iniciar sesión de nuevo." cta="Ver glosario" href="/es/docs/glossary?term=Refresh+Tokens">tokens de actualización</Tooltip> se usan para obtener un nuevo Token de acceso o ID Token después de que el anterior haya expirado. (Para obtener más información sobre los tokens de actualización, lea [Refresh Tokens](/es/docs/secure/tokens/refresh-tokens).) El `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 para siempre.
</Warning>

<div id="call-your-api">
  ### Llama a tu API
</div>

Para llamar a tu API, la aplicación debe enviar el Token de acceso obtenido como un 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 ACCESS_TOKEN' \
    --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 ACCESS_TOKEN");
  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 ACCESS_TOKEN")

  	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 ACCESS_TOKEN")
    .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 ACCESS_TOKEN'}
  };

  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 ACCESS_TOKEN",
      "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 ACCESS_TOKEN"
      }

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

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

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

Ya has recibido un Token de actualización si has seguido este tutorial y has completado lo siguiente:

* configuraste tu API para permitir el acceso sin conexión
* incluiste el scope `offline_access` cuando iniciaste la solicitud de authentication 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. Normalmente, un usuario solo necesitará un nuevo Token de acceso después de que el anterior expire o cuando obtenga acceso a un recurso nuevo por primera vez. No es una buena práctica llamar al endpoint para obtener un nuevo Token de acceso cada vez que llamas a una API, y Auth0 aplica límites de frecuencia que limitarán la cantidad de solicitudes al endpoint que pueden ejecutarse con el mismo token desde la misma IP.

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

<div id="example-refresh-token-post-to-token-url">
  #### Ejemplo de POST de un Token de actualización 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 'client_secret={yourClientSecret}' \
    --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}&client_secret={yourClientSecret}&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}&client_secret={yourClientSecret}&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}&client_secret={yourClientSecret}&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}',
      client_secret: '{yourClientSecret}',
      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}&client_secret={yourClientSecret}&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 "Error de cURL #:" . $err;
  } else {
    echo $response;
  }
  ```

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

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&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}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D"

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

<div id="refresh-token-request-parameters">
  ##### Parámetros de la solicitud de Token de actualización
</div>

| Nombre del parámetro | Descripción                                                                                                                                                                                                                                         |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`         | Establezca este valor en "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).                                                                             |
| `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/\{yourClientSecret}/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, puede solicitar un conjunto reducido de alcances. Tenga en cuenta que debe codificarse como URL. |

<div id="refresh-token-response">
  #### Respuesta del Token de actualización
</div>

Si todo va bien, recibirás una respuesta `HTTP 200` con una carga útil que incluye un nuevo `access_token`, `id_token` (opcionalmente), la duración del token en segundos (`expires_in`), los valores de `scope` concedidos y `token_type`:

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

<Warning>
  Valida tus tokens antes de guardarlos. Para saber cómo hacerlo, consulta [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>

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

<div id="detect-device-authorization-flow-use">
  ### Detectar el uso del Flujo de autorización de dispositivo
</div>

Puede usar Rules para detectar si la transacción actual utiliza el Flujo de autorización de dispositivo. (Para obtener más información sobre Rules, consulte [Auth0 Rules](/es/docs/customize/rules).) Para ello, verifique la propiedad `protocol` del objeto `context`:

```javascript lines theme={null}
function (user, context, callback) {
   if (context.protocol === 'oauth2-device-code') {
      ...
   }
 
   callback(null, user, context);
}
```

<div id="sample-implementations">
  ### Implementaciones de ejemplo
</div>

* [Entorno de pruebas del flujo de autorización de dispositivo](https://auth0.github.io/device-flow-playground/)
* [AppleTV (Swift)](https://github.com/pushpabrol/auth0-device-flow-appletv): Aplicación sencilla que muestra cómo se puede usar Auth0 con el Flujo de autorización de dispositivo en un AppleTV.
* [CLI (Node.js)](https://gist.github.com/panva/ebaacfe433a8677bdbf458f6e1132045): Implementación de ejemplo de una CLI que usa el Flujo de autorización de dispositivo en lugar del Flujo de código de autorización. La principal diferencia es que tu CLI no necesita alojar un servidor web ni escuchar en un puerto.

<div id="troubleshoot">
  ## Solución de problemas
</div>

Los registros del inquilino se generan para cualquier interacción que tenga lugar y pueden usarse para solucionar problemas. Para obtener más información, consulte [Logs](/es/docs/deploy-monitor/logs).

<div id="error-codes">
  ### Códigos de error
</div>

| Código  | Nombre                                                | Descripción                               |
| ------- | ----------------------------------------------------- | ----------------------------------------- |
| `fdeaz` | Error en la solicitud de autorización del dispositivo |                                           |
| `fdeac` | Error en la activación del dispositivo                |                                           |
| `fdecc` | El usuario canceló la confirmación del dispositivo    |                                           |
| `fede`  | Error en el intercambio                               | Código de dispositivo por token de acceso |
| `sede`  | Intercambio exitoso                                   | Código de dispositivo por token de acceso |

<div id="limitations">
  ### Limitaciones
</div>

Para usar el Flujo de autorización de dispositivo, los dispositivos deben:

* Admitir Server Name Indication (SNI) cuando se usan [dominios personalizados](/es/docs/customize/custom-domains)
* Tener un [tipo de aplicación de Auth0](/es/docs/get-started/applications) **Native**
* Tener el [método de autenticación del endpoint de token](/es/docs/get-started/applications/application-settings) establecido en **None**
* Ser [conformes a OIDC](/es/docs/get-started/applications/application-settings)
* No haberse creado mediante [Dynamic Client Registration](/es/docs/get-started/applications/dynamic-client-registration)

Además, el Flujo de autorización de dispositivo no permite:

* [Social Connections](/es/docs/authenticate/identity-providers/social-identity-providers) que usan [claves de desarrollador de Auth0](/es/docs/authenticate/identity-providers/social-identity-providers/devkeys), a menos que estés usando la [experiencia de Universal Login](/es/docs/authenticate/login/auth0-universal-login/universal-login-vs-classic-login/universal-experience)
* Acceder a parámetros de la cadena de consulta desde la página de inicio de sesión alojada, Rules o Actions
* [vinculación de cuentas de usuario](/es/docs/manage-users/user-accounts/user-account-linking)

Admitimos el Draft 15 completo, excepto <Tooltip tip="Cliente confidencial: un cliente (aplicación) que puede almacenar credenciales de forma segura mediante un servidor backend de confianza. Algunos ejemplos son una aplicación web con un backend seguro y una aplicación de máquina a máquina (M2M)." cta="Ver glosario" href="/es/docs/glossary?term=confidential+Clients">clientes confidenciales</Tooltip>. Para obtener más información, consulta [OAuth 2.0 Device Authorization Grant Draft 15 en ietf.org](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15).

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

* [Marco 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)
* [Logs](/es/docs/deploy-monitor/logs)
