> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Aprende a crear una página de error personalizada para errores de autorización.

# Personalizar páginas de error

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

Cuando se produce un error de autorización y la URL de callback es válida, el <Tooltip tip="Servidor de autorización: servidor centralizado que ayuda a definir los límites del acceso de un usuario. Por ejemplo, su 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> devuelve los parámetros `error` y `state` correspondientes a su URL de callback. Si la URL de callback no es válida, la aplicación mostrará la [página de error predeterminada de Auth0](/es/docs/authenticate/login/auth0-universal-login/error-pages).

La aplicación también puede mostrar la página de error predeterminada de Auth0 por motivos distintos de una URL de callback no válida, como los siguientes:

* Faltan parámetros obligatorios al llamar al [endpoint Login](https://auth0.com/docs/api/authentication#login) de la Authentication API de Auth0.
* El usuario abre un enlace de restablecimiento de contraseña caducado (cuando se usa la experiencia de Classic Login).
* El usuario abre una página de Login guardada en marcadores y no se especifica una [ruta de Login predeterminada](/es/docs/authenticate/login/auth0-universal-login/configure-default-login-routes).

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

Si decide configurar una página de error personalizada, el Servidor de autorización devolverá parámetros añadidos a la URL como cadena de consulta.

| Parámetro           | Descripción                                                                   |
| ------------------- | ----------------------------------------------------------------------------- |
| `client_id`         | Identificador de la aplicación de Auth0.                                      |
| `connection`        | Conexión usada en el momento del error.                                       |
| `lang`              | Idioma configurado para usar en el momento del error.                         |
| `error`             | Código del error.                                                             |
| `error_description` | Descripción del error.                                                        |
| `tracking`          | Identificador que usa Auth0 para encontrar errores en los registros internos. |

Los parámetros que se muestran varían según el tipo de error y son específicos de la solicitud. Por ejemplo, si la solicitud que produjo un error no contenía un `client_id`, el Servidor de autorización no devolverá el parámetro `client_id`.

<div id="display-a-custom-error-page">
  ## Mostrar una página de error personalizada
</div>

Si desea mostrar una página de error personalizada, tiene dos opciones:

1. Redirigir a los usuarios a una página de error personalizada mediante Auth0 Dashboard o Auth0 Management API.
2. Configurar Auth0 para que muestre una página de error personalizada en su nombre mediante Management API.

<div id="redirect-users-to-a-custom-error-page-using-the-dashboard">
  ### Redirigir a los usuarios a una página de error personalizada desde el Dashboard
</div>

Use el Dashboard para configurar Auth0 y redirigir a los usuarios a una página de error personalizada:

1. Vaya a [Auth0 Dashboard > Tenant Settings](https://manage.auth0.com/#/tenant/).
2. Busque la sección **Error Pages**.
3. Seleccione la opción **Redirect users to your own error page**.
4. Introduzca la URL de la página de error que desea que vean los usuarios y seleccione **Save**.

<div id="redirect-users-to-a-custom-error-page-using-the-management-api">
  ### Redirija a los usuarios a una página de error personalizada con la Management API
</div>

Use el endpoint [Actualizar la configuración del tenant](https://auth0.com/docs/api/management/v2/#!/Tenants/patch_settings) de la <Tooltip tip="Management API: Un producto que permite a los clientes realizar tareas administrativas." cta="Ver glosario" href="/es/docs/glossary?term=Management+API">Management API</Tooltip>. Reemplace el valor del marcador de posición `{mgmtApiAccessToken}` por su <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> de la Management API y actualice el valor del campo `url` en el cuerpo JSON para que apunte a la página de error.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url 'https://{yourDomain}/api/v2/tenants/settings' \
    --header 'authorization: Bearer {mgmtApiAccessToken}' \
    --header 'content-type: application/json' \
    --data '{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/api/v2/tenants/settings");
  var request = new RestRequest(Method.PATCH);
  request.AddHeader("authorization", "Bearer {mgmtApiAccessToken}");
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}", 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}/api/v2/tenants/settings"

  	payload := strings.NewReader("{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}")

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

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

  	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<String> response = Unirest.patch("https://{yourDomain}/api/v2/tenants/settings")
    .header("authorization", "Bearer {mgmtApiAccessToken}")
    .header("content-type", "application/json")
    .body("{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}")
    .asString();
  ```

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

  var options = {
    method: 'PATCH',
    url: 'https://{yourDomain}/api/v2/tenants/settings',
    headers: {
      authorization: 'Bearer {mgmtApiAccessToken}',
      'content-type': 'application/json'
    },
    data: {error_page: {html: '', show_log_link: false, url: 'http://www.example.com'}}
  };

  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}/api/v2/tenants/settings",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "PATCH",
    CURLOPT_POSTFIELDS => "{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {mgmtApiAccessToken}",
      "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 theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}"

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

  conn.request("PATCH", "/{yourDomain}/api/v2/tenants/settings", 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}/api/v2/tenants/settings")

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

  request = Net::HTTP::Patch.new(url)
  request["authorization"] = 'Bearer {mgmtApiAccessToken}'
  request["content-type"] = 'application/json'
  request.body = "{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}"

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

| Valor                   | Descripción                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `MGMT_API_ACCESS_TOKEN` | [Token de acceso para la Management API](https://auth0.com/docs/api/management/v2/tokens) con el scope `update:tenant_settings`. |
| `show_log_link`         | Indica si se mostrará un enlace al error en los registros de su inquilino. Los valores válidos son `true` y `false`.             |
| `url`                   | Ubicación de la página de error personalizada a la que quiere redirigir.                                                         |

<div id="render-a-custom-error-page">
  ### Mostrar una página de error personalizada
</div>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Cuando los errores se muestran dentro del widget de Classic Login (por ejemplo, un enlace de restablecimiento de contraseña vencido), no se mostrará una página de error personalizada alojada en Auth0, aunque esté configurada.
</Callout>

Use el endpoint [Actualizar la configuración del tenant](https://auth0.com/docs/api/management/v2/#!/Tenants/patch_settings) de la Management API. Reemplace el valor del marcador de posición `{mgmtApiAccessToken}` por su Token de acceso de la Management API y actualice el valor del campo `html` en el cuerpo JSON por una cadena que contenga el HTML de su página.

Puede usar la sintaxis Liquid para incluir las siguientes variables:

* `{client_id}`
* `{connection}`
* `{lang}`
* `{error}`
* `{error_description}`
* `{tracking}`

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request PATCH \
    --url https://login.auth0.com/api/v2/tenants/settings \
    --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
    --header 'content-type: application/json' \
    --data '{"error_page": {"html": "<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'\''now'\'' | date: '\''%Y %h'\''}}.</h1>", "show_log_link": false, "url": ""}}'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://login.auth0.com/api/v2/tenants/settings");
  var request = new RestRequest(Method.PATCH);
  request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{\"error_page\": {\"html\": \"

  # {{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.

  \", \"show_log_link\": false, \"url\": \"\"}}", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

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

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

  func main() {

  	url := "https://login.auth0.com/api/v2/tenants/settings"

  	payload := strings.NewReader("{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}")

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

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

  	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<String> response = Unirest.patch("https://login.auth0.com/api/v2/tenants/settings")
    .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
    .header("content-type", "application/json")
    .body("{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}")
    .asString();
  ```

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

  var options = {
    method: 'PATCH',
    url: 'https://login.auth0.com/api/v2/tenants/settings',
    headers: {
      authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
      'content-type': 'application/json'
    },
    data: {
      error_page: {
        html: '<h1>{{error | escape }} {{error_description | escape }} This error was generated {{\'now\' | date: \'%Y %h\'}}.</h1>',
        show_log_link: false,
        url: ''
      }
    }
  };

  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://login.auth0.com/api/v2/tenants/settings",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "PATCH",
    CURLOPT_POSTFIELDS => "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer MGMT_API_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("login.auth0.com")

  payload = "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}"

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

  conn.request("PATCH", "/api/v2/tenants/settings", payload, 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://login.auth0.com/api/v2/tenants/settings")

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

  request = Net::HTTP::Patch.new(url)
  request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
  request["content-type"] = 'application/json'
  request.body = "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}"

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

| Valor                   | Descripción                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `MGMT_API_ACCESS_TOKEN` | [Token de acceso para la Management API](https://auth0.com/docs/api/management/v2/tokens) con el scope `update:tenant_settings`. |
| `show_log_link`         | Indica si se debe mostrar un enlace al error en los registros de tu inquilino. Los valores válidos son `true` y `false`.         |
| `html`                  | HTML de la página de error personalizada que quieres mostrar.                                                                    |

Para evitar vulnerabilidades de XSS, sanitiza tu plantilla personalizada con los filtros [escape](https://shopify.github.io/liquid/filters/escape/) y [strip\_html](https://shopify.github.io/liquid/filters/strip_html/) de Liquid.

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

* [Auth0 Universal Login](/es/docs/authenticate/login/auth0-universal-login)
