# Adicionando um botão de Sign-In with HF ao seu Space

Você pode habilitar um fluxo de login integrado no seu Space criando e associando de forma transparente um aplicativo [OAuth/OpenID connect](https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc) para que os usuários façam login com sua conta do HF.

Isso habilita novos casos de uso para o seu Space. Por exemplo, quando combinado com [Storage Buckets](https://huggingface.co/docs/hub/storage-buckets), um Space de IA generativa pode permitir que os usuários façam login para acessar suas gerações anteriores, acessíveis apenas a eles.

> [!TIP]
> Este guia o levará pelo processo de integrar um botão *Sign-In with HF* em qualquer Space. Se você está buscando um método rápido e simples para implementar isso em um Space **Gradio**, dê uma olhada na sua [integração embutida](https://www.gradio.app/guides/sharing-your-app#o-auth-login-via-hugging-face).

> [!TIP]
> Você também pode usar o fluxo de OAuth da HF para criar um fluxo de "Entrar com HF" em qualquer site ou aplicativo, fora dos Spaces. [Leia nossa página geral sobre OAuth](./oauth).

## Criar um aplicativo OAuth

Tudo o que você precisa fazer é adicionar `hf_oauth: true` aos metadados do seu Space no arquivo `README.md`.

Aqui está um exemplo de metadados para um Espaço do 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
```

Você pode consultar a [documentação de referência de configuração](./spaces-config-reference) para mais informações.

Isso adicionará as seguintes [variáveis de ambiente](https://huggingface.co/docs/hub/spaces-overview#built-in-environment-variables) ao seu espaço:

- `OAUTH_CLIENT_ID`: o ID do cliente do seu aplicativo OAuth (público)
- `OAUTH_CLIENT_SECRET`: o segredo do cliente do seu aplicativo OAuth
- `OAUTH_SCOPES`: escopos acessíveis pelo seu aplicativo OAuth.
- `OPENID_PROVIDER_URL`: A URL do provedor OpenID. Os metadados do OpenID estarão disponíveis em [`{OPENID_PROVIDER_URL}/.well-known/openid-configuration`](https://huggingface.co/.well-known/openid-configuration).

Como qualquer outra variável de ambiente, você pode usá-las no seu código usando, por exemplo, `os.getenv("OAUTH_CLIENT_ID")`.

## URLs de redirecionamento

Você pode usar qualquer URL de redirecionamento que desejar, desde que ela aponte para o seu Space.

Observe que `SPACE_HOST` está [disponível](https://huggingface.co/docs/hub/spaces-overview#built-in-environment-variables) como uma variável de ambiente.

Por exemplo, você pode usar `https://{SPACE_HOST}/login/callback` como URI de redirecionamento.

## Escopos

Os seguintes escopos são sempre incluídos para Spaces:

- `openid`: Receba um token de ID em adição ao token de acesso.
- `profile`: Lê as informações do perfil do usuário (nome de usuário, avatar, etc.)

Esses escopos são opcionais e podem ser adicionados definindo `hf_oauth_scopes` nos metadados do seu Space:

- `email`: Lê o endereço de e-mail do usuário.
- `read-billing`: Saber se o usuário tem um método de pagamento configurado.
- `read-memberships`: Lê as organizações às quais o usuário pertence e seu papel em cada uma delas. Isso não concede acesso às configurações ou recursos das organizações.
- `read-repos`: Lê os repositórios pessoais do usuário.
- `gated-repos`: Lê o conteúdo de repositórios públicos com acesso restrito (gated) para os quais o usuário foi autorizado. Diferentemente de `read-repos`, isso não concede acesso a repositórios privados.
- `contribute-repos`: Cria repositórios e acessa aqueles criados por este aplicativo. Não pode acessar nenhum outro repositório, a menos que permissões adicionais sejam concedidas.
- `write-repos`: Lê e grava nos repositórios pessoais do usuário.
- `manage-repos`: Gerencia totalmente os repositórios pessoais do usuário, incluindo a criação e a exclusão deles.
- `read-collections`: Lê as coleções pessoais do usuário.
- `write-collections`: Lê e grava as coleções pessoais do usuário, incluindo a criação e a exclusão delas.
- `inference-api`: Faça solicitações de inferência para [Inference Providers](https://huggingface.co/docs/inference-providers/index) em nome do usuário.
- `read-endpoints`: Exibe os [Inference Endpoints](https://huggingface.co/docs/inference-endpoints/index) do usuário e faz solicitações de inferência a eles em nome do usuário.
- `write-endpoints`: Gerencia os Inference Endpoints do usuário, incluindo a criação e a exclusão deles. Inclui acesso `read-endpoints`.
- `jobs`: Executar [jobs](https://huggingface.co/docs/huggingface_hub/main/en/guides/jobs)
- `webhooks`: Gerenciar [webhooks](https://huggingface.co/docs/huggingface_hub/main/en/guides/webhooks)
- `write-discussions`: Abre discussões e Pull Requests em nome do usuário, bem como interage com discussões (incluindo reações, publicação/edição de comentários, fechamento de discussões, ...). Para abrir Pull Requests em repositórios privados, você precisa solicitar também o escopo `read-repos`.

## Acessando recursos da organização

Por padrão, o aplicativo oauth não precisa acessar recursos da organização.

Mas alguns escopos, como `read-repos` ou `read-billing`, também se aplicam a organizações.

O usuário pode selecionar quais organizações conceder acesso ao autorizar o aplicativo. Se você exigir acesso a uma organização específica, pode adicionar `orgIds=ORG_ID` como um parâmetro de consulta à URL de autorização do OAuth. Você deve substituir `ORG_ID` pelo ID da organização, que está disponível no campo `organizations.sub` da resposta de userinfo.

## Adicionando o botão ao seu Space

Agora você tem todas as informações para adicionar um botão "Sign-in with HF" ao seu Space. Algumas bibliotecas ([Python](https://github.com/lepture/authlib), [NodeJS](https://github.com/panva/node-openid-client)) podem ajudar você a implementar o protocolo OpenID/OAuth.

Gradio e huggingface.js também oferecem **suporte nativo**, o que torna a implementação do botão Sign-in with HF muito simples; você pode conferir os guias associados com [gradio](https://www.gradio.app/guides/sharing-your-app#o-auth-login-via-hugging-face) e com [huggingface.js](https://huggingface.co/docs/huggingface.js/hub/README#oauth-login).

Basicamente, você precisa:

- Redirecione o usuário para `https://huggingface.co/oauth/authorize?redirect_uri={REDIRECT_URI}&scope=openid%20profile&client_id={CLIENT_ID}&state={STATE}`, onde `STATE` é uma string aleatória que você precisará verificar posteriormente.
- Trate o callback em `/auth/callback` ou `/login/callback` (ou sua própria URL de callback personalizada) e verifique o parâmetro `state`.
- Use o parâmetro de consulta `code` para obter um token de acesso e um token de id de `https://huggingface.co/oauth/token` (requisição POST com `client_id`, `code`, `grant_type=authorization_code` e `redirect_uri` como dados de formulário, e com `Authorization: Basic {base64(client_id:client_secret)}` como cabeçalho).

> [!WARNING]
> Você deve usar `target=_blank` no botão para abrir a página de login em uma nova aba, a menos que execute o espaço fora do seu `iframe`. Caso contrário, você pode encontrar problemas com cookies em alguns navegadores.

## Exemplos:

- [Aplicativo de teste do Gradio](https://huggingface.co/spaces/Wauplin/gradio-oauth-test)
- [HuggingChat (NodeJS/SvelteKit)](https://huggingface.co/spaces/huggingchat/chat-ui)
- [Widgets de inferência (Auth.js/SvelteKit)](https://huggingface.co/spaces/huggingfacejs/inference-widgets) usa o escopo `inference-api` para fazer solicitações de inferência em nome do usuário.
- [Cliente em um espaço estático (huggingface.js)](https://huggingface.co/spaces/huggingfacejs/client-side-oauth) - exemplo muito simples em JavaScript.

Exemplo 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);
```

