# Añadir un botón de Iniciar sesión con HF a tu Space

Puedes habilitar un flujo de inicio de sesión integrado en tu Space creando y asociando de forma transparente una aplicación de [OAuth/OpenID connect](https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc) para que los usuarios inicien sesión con su cuenta de HF.

Esto habilita nuevos casos de uso para tu Space. Por ejemplo, cuando se combina con [Storage Buckets](https://huggingface.co/docs/hub/storage-buckets), un Space de IA generativa podría permitir a los usuarios iniciar sesión para acceder a sus generaciones anteriores, accesibles solo para ellos.

> [!TIP]
> Esta guía te guiará a través del proceso de integrar un botón de *Iniciar sesión con HF* en cualquier Space. Si buscas un método rápido y sencillo para implementarlo en un Space de **Gradio**, echa un vistazo a su [integración integrada](https://www.gradio.app/guides/sharing-your-app#o-auth-login-via-hugging-face).

> [!TIP]
> También puedes usar el flujo de OAuth de HF para crear un flujo de "Iniciar sesión con HF" en cualquier sitio web o aplicación, fuera de Spaces. [Lee nuestra página general de OAuth](./oauth).

## Crear una aplicación de OAuth

Todo lo que tienes que hacer es añadir `hf_oauth: true` a los metadatos de tu Space dentro de tu archivo `README.md`.

Aquí hay un ejemplo de metadatos para un Espacio de Gradio:

```yaml
title: Gradio Oauth Test
emoji: 🏆
colorFrom: pink
colorTo: pink
sdk: gradio
sdk_version: 3.40.0
python_version: 3.10.6
app_file: app.py

hf_oauth: true
# optional, default duration is 8 hours/480 minutes. Max duration is 30 days/43200 minutes.
hf_oauth_expiration_minutes: 480
# optional, see "Scopes" below. "openid profile" is always included.
hf_oauth_scopes:
 - read-repos
 - gated-repos
 - write-repos
 - manage-repos
 - inference-api
# optional, restrict access to members of specific organizations
hf_oauth_authorized_org: ORG_NAME
hf_oauth_authorized_org:
  - ORG_NAME1
  - ORG_NAME2
```

Puede consultar la [documentación de referencia de configuración](./spaces-config-reference) para obtener más información.

Esto añadirá las siguientes [variables de entorno](https://huggingface.co/docs/hub/spaces-overview#built-in-environment-variables) a tu espacio:

- `OAUTH_CLIENT_ID`: el ID de cliente de tu aplicación de OAuth (público)
- `OAUTH_CLIENT_SECRET`: el secreto de cliente de tu aplicación de OAuth
- `OAUTH_SCOPES`: ámbitos accesibles por tu aplicación de OAuth.
- `OPENID_PROVIDER_URL`: La URL del proveedor de OpenID. Los metadatos de OpenID estarán disponibles en [`{OPENID_PROVIDER_URL}/.well-known/openid-configuration`](https://huggingface.co/.well-known/openid-configuration).

Como con cualquier otra variable de entorno, puedes usarlas en tu código mediante `os.getenv("OAUTH_CLIENT_ID")`, por ejemplo.

## URLs de redirección

Puedes usar cualquier URL de redirección que desees, siempre que apunte a tu Space.

Tenga en cuenta que `SPACE_HOST` está [disponible](https://huggingface.co/docs/hub/spaces-overview#built-in-environment-variables) como variable de entorno.

Por ejemplo, puedes usar `https://{SPACE_HOST}/login/callback` como URI de redirección.

## Ámbitos

Los siguientes ámbitos siempre se incluyen para Spaces:

- `openid`: Recibe un token de ID además del token de acceso.
- `profile`: Lee la información del perfil del usuario (nombre de usuario, avatar, etc.)

Esos ámbitos son opcionales y se pueden agregar configurando `hf_oauth_scopes` en los metadatos de tu Space:

- `email`: Lee la dirección de correo electrónico del usuario.
- `read-billing`: Saber si el usuario tiene un método de pago configurado.
- `read-memberships`: Lee las organizaciones a las que pertenece el usuario y su rol en cada una de ellas. Esto no otorga acceso a la configuración ni a los recursos de las organizaciones.
- `read-repos`: Lee los repositorios personales del usuario.
- `gated-repos`: Lee el contenido de los repositorios públicos con acceso restringido a los que el usuario ha sido autorizado. A diferencia de `read-repos`, esto no otorga acceso a repositorios privados.
- `contribute-repos`: Crea repositorios y accede a los creados por esta aplicación. No puede acceder a ningún otro repositorio a menos que se otorguen permisos adicionales.
- `write-repos`: Lee y escribe los repositorios personales del usuario.
- `manage-repos`: Gestionar por completo los repositorios personales del usuario, incluida su creación y eliminación.
- `read-collections`: Lee las colecciones personales del usuario.
- `write-collections`: Lee y escribe las colecciones personales del usuario, incluida su creación y eliminación.
- `inference-api`: Realiza solicitudes de inferencia a [Inference Providers](https://huggingface.co/docs/inference-providers/index) en nombre del usuario.
- `read-endpoints`: Ver los [Inference Endpoints](https://huggingface.co/docs/inference-endpoints/index) del usuario y realizar solicitudes de inferencia a su nombre.
- `write-endpoints`: Gestiona los Inference Endpoints del usuario, incluida su creación y eliminación. Incluye el acceso `read-endpoints`.
- `jobs`: Ejecutar [jobs](https://huggingface.co/docs/huggingface_hub/main/en/guides/jobs)
- `webhooks`: Gestionar [webhooks](https://huggingface.co/docs/huggingface_hub/main/en/guides/webhooks)
- `write-discussions`: Abre discusiones y Pull Requests en nombre del usuario e interactúa con las discusiones (incluidas reacciones, publicación/edición de comentarios, cierre de discusiones, ...). Para abrir Pull Requests en repositorios privados, también necesitas solicitar el ámbito `read-repos`.

## Acceso a los recursos de la organización

Por defecto, la aplicación de oauth no necesita acceder a los recursos de la organización.

Pero algunos ámbitos, como `read-repos` o `read-billing`, también se aplican a las organizaciones.

El usuario puede seleccionar a qué organizaciones otorgar acceso al autorizar la aplicación. Si se requiere acceso a una organización específica, se puede agregar `orgIds=ORG_ID` como parámetro de consulta a la URL de autorización de OAuth. Debe reemplazar `ORG_ID` con el ID de la organización, que está disponible en el campo `organizations.sub` de la respuesta de userinfo.

## Añadir el botón a tu Space

Ahora tienes toda la información para añadir un botón de "Sign-in with HF" a tu Space. Algunas bibliotecas ([Python](https://github.com/lepture/authlib), [NodeJS](https://github.com/panva/node-openid-client)) pueden ayudarte a implementar el protocolo OpenID/OAuth.

Gradio y huggingface.js también ofrecen **soporte integrado**, lo que facilita la implementación del botón Sign-in with HF; puedes consultar las guías asociadas con [gradio](https://www.gradio.app/guides/sharing-your-app#o-auth-login-via-hugging-face) y con [huggingface.js](https://huggingface.co/docs/huggingface.js/hub/README#oauth-login).

Básicamente, necesitas:

- Redirija al usuario a `https://huggingface.co/oauth/authorize?redirect_uri={REDIRECT_URI}&scope=openid%20profile&client_id={CLIENT_ID}&state={STATE}`, donde `STATE` es una cadena aleatoria que deberá verificar más adelante.
- Maneja el callback en `/auth/callback` o `/login/callback` (o tu propia URL de callback personalizada) y verifica el parámetro `state`.
- Use the query parameter `code` para obtener un token de acceso y un token de identidad desde `https://huggingface.co/oauth/token` (solicitud POST con `client_id`, `code`, `grant_type=authorization_code` y `redirect_uri` como datos del formulario, y con `Authorization: Basic {base64(client_id:client_secret)}` como cabecera).


Use the query parameter `code` para obtener un token de acceso y un token de identidad desde `https://huggingface.co/oauth/token` (solicitud POST con `client_id`, `code`, `grant_type=authorization_code` y `redirect_uri` como datos del formulario, y con `Authorization: Basic {base64(client_id:client_secret)}` como cabecera).

> [!WARNING]
> Debes usar `target=_blank` en el botón para abrir la página de inicio de sesión en una nueva pestaña, a menos que ejecutes el espacio fuera de su `iframe`. De lo contrario, es posible que encuentres problemas con las cookies en algunos navegadores.

## Ejemplos:

- [Aplicación de prueba de Gradio](https://huggingface.co/spaces/Wauplin/gradio-oauth-test)
- [HuggingChat (NodeJS/SvelteKit)](https://huggingface.co/spaces/huggingchat/chat-ui)
- [Widgets de inferencia (Auth.js/SvelteKit)](https://huggingface.co/spaces/huggingfacejs/inference-widgets) utiliza el ámbito `inference-api` para realizar solicitudes de inferencia en nombre del usuario.
- [En el lado del cliente en un espacio estático (huggingface.js)](https://huggingface.co/spaces/huggingfacejs/client-side-oauth) - ejemplo de JavaScript muy simple.

Ejemplo de código JS:

```js
import { oauthLoginUrl, oauthHandleRedirectIfPresent } from "@huggingface/hub";

const oauthResult = await oauthHandleRedirectIfPresent();

if (!oauthResult) {
  // If the user is not logged in, redirect to the login page
  window.location.href = await oauthLoginUrl();
}

// You can use oauthResult.accessToken, oauthResult.userInfo among other things
console.log(oauthResult);
```

