> ## 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 propia API desde aplicaciones de alta confianza mediante el flujo de contraseña del propietario del recurso.

# Llame a su API mediante el flujo de contraseña del propietario del recurso

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 mediante el flujo de contraseña del propietario del recurso. Si quieres obtener más información sobre cómo funciona el flujo y por qué deberías usarlo, consulta [flujo de contraseña del propietario del recurso](/es/docs/get-started/authentication-and-authorization-flow/resource-owner-password-flow).
</Callout>

<Warning>
  Debido a que el flujo de contraseña del propietario del recurso (ROP) implica que la aplicación gestione la contraseña del usuario, no debe utilizarse en clientes de terceros.
</Warning>

Auth0 facilita la implementación en tu aplicación del flujo de contraseña del <Tooltip tip="Propietario del recurso: entidad (como un usuario o una aplicación) capaz de conceder acceso a un recurso protegido." cta="Ver glosario" href="/es/docs/glossary?term=Resource+Owner">propietario del recurso</Tooltip> (a veces llamado concesión de contraseña del propietario del recurso o ROPG) mediante la [Authentication API](https://auth0.com/docs/api/authentication). Sigue leyendo para aprender a llamar a nuestra API directamente.

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

**Antes de comenzar este tutorial:**

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

  * Seleccione un **Tipo de aplicación** de **Aplicaciones web regulares**.
  * Agregue una **URL de devolución de llamada permitida** de `{https://yourApp/callback}`. Este campo no puede dejarse sin definir o se devolverá un mensaje de error.
  * Asegúrese de que los **Tipos de concesión** de su aplicación incluyan **Password**. Para saber cómo hacerlo, lea [Actualizar tipos de concesión](/es/docs/get-started/applications/update-grant-types).
  * Si desea que su aplicación pueda usar tokens de actualización, asegúrese de que los **Tipos de concesión** de la aplicación incluyan **Token de actualización**. Para saber cómo hacerlo, lea [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, lea [Tokens de actualización](/es/docs/secure/tokens/refresh-tokens).
* [Registre su API en Auth0](/es/docs/get-started/auth0-overview/set-up-apis)

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

  * Asegúrese de que su conexión pueda autenticar usuarios con nombre de usuario y contraseña (por ejemplo, [conexiones de base de datos](/es/docs/get-started/applications/set-up-database-connections), o AD/LDAP, ADFS o Azure Active Directory [conexiones empresariales](/es/docs/authenticate/identity-providers/enterprise-identity-providers)).
* Actualice o deshabilite cualquier [regla](/es/docs/customize/rules), de modo que solo afecten a conexiones específicas. Si obtiene un error `access_denied` al probar el Password Owner Resource Grant, esto podría deberse a una regla de control de acceso.

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

1. [Configurar el inquilino](#configure-tenant):Establece la conexión predeterminada del inquilino.
2. [Solicitar tokens](#request-tokens):
   Intercambia tu código de autorización por tokens.
3. [Llamar a la API](#call-api):
   Usa el Token de acceso obtenido para llamar a tu API.
4. [Tokens de actualización](#refresh-tokens):
   Usa un Token de actualización para solicitar nuevos tokens cuando caduquen los actuales.

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

Opcional: [Configurar compatibilidad con realm](#configure-realm-support)

Opcional: [Configurar MFA](#configure-mfa)

Opcional: [Configurar protección contra ataques](#configure-anomaly-detection)

<div id="configure-tenant">
  ### Configurar el inquilino
</div>

El flujo de contraseña del propietario del recurso requiere una conexión capaz de autenticar usuarios mediante username y contraseña, por lo que debe configurar la conexión predeterminada del inquilino.

1. Vaya a [Auth0 Dashboard > Tenant Settings](https://manage.auth0.com/#/tenant) y desplácese hacia abajo hasta encontrar la configuración **Default Directory**.
2. Introduzca el nombre de la conexión que desea usar. Asegúrese de que pueda autenticar usuarios mediante username y contraseña.

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

Para llamar a tu API, primero debes obtener las credenciales del usuario, normalmente mediante un formulario interactivo. Una vez que tu aplicación tenga las credenciales, debes canjearlas por tokens. Para ello, debes hacer una solicitud `POST` a la [URL del token](https://auth0.com/docs/api/authentication#resource-owner-password).

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

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=password \
    --data 'username={username}' \
    --data 'password={password}' \
    --data 'audience={yourApiIdentifier}' \
    --data scope=read:sample \
    --data 'client_id={yourClientId}' \
    --data 'client_secret={yourClientSecret}'
  ```

  ```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=password&username=%7Busername%7D&password=%7Bpassword%7D&audience=%7ByourApiIdentifier%7D&scope=read%3Asample&client_id={yourClientId}&client_secret=%7ByourClientSecret%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=password&username=%7Busername%7D&password=%7Bpassword%7D&audience=%7ByourApiIdentifier%7D&scope=read%3Asample&client_id={yourClientId}&client_secret=%7ByourClientSecret%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=password&username=%7Busername%7D&password=%7Bpassword%7D&audience=%7ByourApiIdentifier%7D&scope=read%3Asample&client_id={yourClientId}&client_secret=%7ByourClientSecret%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: 'password',
      username: '{username}',
      password: '{password}',
      audience: '{yourApiIdentifier}',
      scope: 'read:sample',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}'
    })
  };

  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=password&username=%7Busername%7D&password=%7Bpassword%7D&audience=%7ByourApiIdentifier%7D&scope=read%3Asample&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

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

  curl_close($curl);

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

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

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=password&username=%7Busername%7D&password=%7Bpassword%7D&audience=%7ByourApiIdentifier%7D&scope=read%3Asample&client_id={yourClientId}&client_secret=%7ByourClientSecret%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=password&username=%7Busername%7D&password=%7Bpassword%7D&audience=%7ByourApiIdentifier%7D&scope=read%3Asample&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D"

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

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

| Nombre del parámetro    | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`            | Establezca este valor en `password`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `username`              | El username introducido por el usuario.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `password`              | La contraseña introducida por el usuario.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `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_assertion`      | Un JWT que contiene una aserción firmada con las credenciales de su aplicación. Es obligatorio cuando Private Key JWT es el método de autenticación de su aplicación.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `client_assertion_type` | El valor es `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`. Es obligatorio cuando Private Key JWT es el método de autenticación de la aplicación.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `client_secret`         | El Secreto del cliente de su aplicación. Es obligatorio cuando Client Secret es el método de autenticación de la aplicación y la [configuración de la aplicación](https://manage.auth0.com/#/applications/\{yourClientId}/settings) es `Post` o `Basic`. Si su aplicación no es de alta confianza (por ejemplo, una SPA), no establezca este parámetro.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `audience`              | La audiencia del token, es decir, su API. Puede encontrarla en el campo **Identificador** de la [pestaña de configuración de su API](https://manage.auth0.com/#/apis).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scope`                 | Especifica los [alcances](/es/docs/get-started/apis/scopes) para los que desea solicitar autorización, que determinan qué claims (o atributos de usuario) desea que se devuelvan. Deben estar separados por espacios. Puede solicitar cualquiera de los [alcances estándar de OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) relacionados con el usuario, como `profile` o `email`, [claims personalizados](/es/docs/secure/tokens/json-web-tokens/json-web-token-claims#custom-claims) que sigan un [formato con espacio de nombres](/es/docs/secure/tokens/json-web-tokens/create-custom-claims), o cualquier alcance compatible con la API de destino (por ejemplo, `read:contacts`). 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)). |

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

Si todo va bien, recibirás una respuesta `HTTP 200` con una carga útil que incluye los valores `access_token`, `refresh_token`, `id_token`, `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": 36000
}
```

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

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

<Card title="Flujo de contraseña del propietario del recurso y alcances estándar">
  Debido a que proporcionar una contraseña otorga acceso total, cualquier intercambio basado en contraseña da acceso a todos los alcances. Por ejemplo, si no incluye [alcances de API](/es/docs/get-started/apis/scopes/api-scopes) en la solicitud, todos los alcances de la API se incluirán en el Token de acceso. Del mismo modo, si incluye solo el scope `openid` en la solicitud, se devolverán todos los [alcances](/es/docs/get-started/apis/scopes/openid-connect-scopes) estándar de OpenID Connect relacionados con `openid`. En estos casos, el parámetro `scope` se incluirá en la respuesta y enumerará los alcances emitidos.
</Card>

<Card title="Obtener información de usuario sin un ID Token">
  Si necesita información del usuario, incluya el scope `openid` en su solicitud. Si la API usa `RS256` como [algoritmo de firma](/es/docs/get-started/applications/signing-algorithms), el Token de acceso incluirá `/userinfo` como una audiencia válida, lo que significa que puede usarlo para llamar al [endpoint /userinfo](https://auth0.com/docs/api/authentication#get-user-info) y recuperar los claims del usuario.
</Card>

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

Para llamar a su API, la aplicación debe enviar el <Tooltip tip="Token de acceso: credencial de autorización, en forma de una cadena opaca o JWT, que se utiliza para acceder a una API." cta="Ver glosario" href="/es/docs/glossary?term=Access+Token">Token de acceso</Tooltip> obtenido como Bearer Token en el encabezado Authorization de la solicitud HTTP.

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

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

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

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

  func main() {

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

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

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

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

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

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

  }
  ```

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

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

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

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

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

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

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

  curl_close($curl);

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

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

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

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

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

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

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

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

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

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

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

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

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

Ya recibiste un [token de actualización](/es/docs/secure/tokens/refresh-tokens) si has seguido este tutorial y completaste lo siguiente:

* configuraste tu API para permitir el acceso sin conexión
* incluiste el scope `offline_access` cuando iniciaste la solicitud de autenticación mediante el [endpoint de autorización](https://auth0.com/docs/api/authentication/reference#authorize-application).

Puedes usar el <Tooltip tip="Token de actualización: token que se usa para obtener un Token de acceso nuevo sin obligar a los usuarios a volver a iniciar sesión." cta="Ver glosario" href="/es/docs/glossary?term=Refresh+Token">Token de actualización</Tooltip> para obtener un nuevo token de acceso. Normalmente, un usuario solo necesitará un nuevo token de acceso cuando 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 restringen la cantidad de solicitudes al endpoint que pueden ejecutarse con el mismo token desde la misma IP.

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

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

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

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

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

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

  func main() {

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

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

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

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

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

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

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

  }
  ```

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

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

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

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

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

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

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

  curl_close($curl);

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

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

  conn = http.client.HTTPSConnection("")

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

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

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

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

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

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

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

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

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

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

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

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

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

Si todo sale bien, recibirás una respuesta `HTTP 200` con una carga útil que incluye un nuevo `access_token`, su duración 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",
  "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">
  ### Ejemplos de casos de uso
</div>

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

Puede usar Actions para cambiar los alcances devueltos de los tokens de acceso y/o agregar claims a los tokens de acceso y a los <Tooltip tip="ID Token: Credencial destinada al propio cliente, en lugar de para acceder a un recurso." cta="Ver glosario" href="/es/docs/glossary?term=ID+Tokens">ID Tokens</Tooltip>. (Para obtener más información sobre Actions, lea [Auth0 Actions](/es/docs/customize/actions).) Para ello, agregue la siguiente Action, que se ejecutará después de que el usuario se autentique:

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

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

Los alcances estarán disponibles en el token después de que se ejecute la Action.

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

<div id="configure-realm-support">
  ### Configurar la compatibilidad con realms
</div>

Auth0 proporciona un grant de extensión que ofrece una funcionalidad similar al grant Resource Owner Password, pero le permite mantener directorios de usuarios separados (que se asignan a conexiones independientes) y especificar cuál usar durante el flujo.

Para usar esta variante, debe:

* Establecer el parámetro de solicitud `grant_type` en `http://auth0.com/oauth/grant-type/password-realm`.
* Enviar un parámetro de solicitud adicional llamado `realm` y establecerlo con el nombre del realm al que pertenece el usuario. Por ejemplo, si ha configurado una conexión de base de datos para empleados internos llamada `employees` y el usuario pertenece a ella, establezca `realm` en `employees`.

<Card title="Conexiones como realms">
  Cualquier conexión que admita autenticación activa puede configurarse como un realm, incluidas las [conexiones de base de datos](/es/docs/get-started/applications/set-up-database-connections), las [conexiones sin contraseña](/es/docs/authenticate/passwordless) y las conexiones empresariales de [AD/LDAP](/es/docs/authenticate/identity-providers/enterprise-identity-providers/active-directory-ldap), [ADFS](/es/docs/authenticate/identity-providers/enterprise-identity-providers/adfs) y [Azure Active Directory](/es/docs/authenticate/identity-providers/enterprise-identity-providers/azure-active-directory/v2).
</Card>

<div id="configure-mfa">
  ### Configurar MFA
</div>

Si necesita usar el flujo de contraseña del propietario del recurso, pero requiere una autenticación más robusta, puede agregar <Tooltip tip="Autenticación multifactor (MFA): proceso de autenticación del usuario que utiliza un factor además del username y la contraseña, como un code por SMS." cta="Ver glosario" href="/es/docs/glossary?term=multi-factor+authentication">autenticación multifactor</Tooltip> (MFA). Para saber cómo hacerlo, consulte [Autenticar con el flujo de contraseña del propietario del recurso con MFA](/es/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa).

<div id="configure-attack-protection">
  ### Configurar la protección contra ataques
</div>

Al usar el flujo de contraseña del propietario del recurso con <Tooltip tip="Protección contra ataques de fuerza bruta: forma de protección contra ataques que protege frente a ataques de fuerza bruta que se producen desde una sola dirección IP y se dirigen a una sola cuenta de usuario." cta="Ver glosario" href="/es/docs/glossary?term=brute-force+protection">protección contra ataques de fuerza bruta</Tooltip>, es posible que algunas funciones de <Tooltip tip="Protección contra ataques de fuerza bruta: forma de protección contra ataques que protege frente a ataques de fuerza bruta que se producen desde una sola dirección IP y se dirigen a una sola cuenta de usuario." cta="Ver glosario" href="/es/docs/glossary?term=attack+protection">protección contra ataques</Tooltip> no funcionen correctamente. Sin embargo, se pueden evitar algunos problemas comunes. Para obtener más información, consulte [Evitar problemas comunes con el flujo de contraseña del propietario del recurso y la protección contra ataques](/es/docs/get-started/authentication-and-authorization-flow/resource-owner-password-flow/avoid-common-issues-with-resource-owner-password-flow-and-attack-protection).

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

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