# Menambahkan tombol Sign-In with HF ke Space Anda

Anda dapat mengaktifkan alur masuk bawaan di Space Anda dengan membuat dan mengaitkan aplikasi [OAuth/OpenID connect](https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc) secara mulus sehingga pengguna dapat masuk menggunakan akun HF mereka.

Hal ini memungkinkan kasus penggunaan baru untuk Space Anda. Misalnya, ketika dikombinasikan dengan [Storage Buckets](https://huggingface.co/docs/hub/storage-buckets), Space AI generatif dapat memungkinkan pengguna untuk masuk dan mengakses generasi sebelumnya mereka, yang hanya dapat diakses oleh mereka.

> [!TIP]
> Panduan ini akan memandu Anda melalui proses mengintegrasikan tombol *Sign-In with HF* ke dalam Space apa pun. Jika Anda mencari metode yang cepat dan sederhana untuk mengimplementasikannya di Space **Gradio**, lihat [integrasi bawaan](https://www.gradio.app/guides/sharing-your-app#o-auth-login-via-hugging-face)-nya.

> [!TIP]
> Anda juga dapat menggunakan alur HF OAuth untuk membuat alur "Sign in with HF" di situs web atau Aplikasi mana pun, di luar Spaces. [Baca halaman OAuth umum kami](./oauth).

## Buat aplikasi OAuth

Yang perlu Anda lakukan adalah menambahkan `hf_oauth: true` ke metadata Space Anda di dalam file `README.md` Anda.

Berikut adalah contoh metadata untuk Gradio Space:

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

Anda dapat melihat [dokumentasi referensi konfigurasi](./spaces-config-reference) untuk informasi lebih lanjut.

Hal ini akan menambahkan [variabel lingkungan](https://huggingface.co/docs/hub/spaces-overview#built-in-environment-variables) berikut ke space Anda:

- `OAUTH_CLIENT_ID`: ID klien aplikasi OAuth Anda (publik)
- `OAUTH_CLIENT_SECRET`: rahasia klien aplikasi OAuth Anda
- `OAUTH_SCOPES`: scope yang dapat diakses oleh aplikasi OAuth Anda.
- `OPENID_PROVIDER_URL`: URL dari penyedia OpenID. Metadata OpenID akan tersedia di [`{OPENID_PROVIDER_URL}/.well-known/openid-configuration`](https://huggingface.co/.well-known/openid-configuration).

Seperti variabel lingkungan lainnya, Anda dapat menggunakannya dalam kode Anda dengan menggunakan `os.getenv("OAUTH_CLIENT_ID")`, misalnya.

## URL pengalihan

Anda dapat menggunakan URL redirect apa pun, selama URL tersebut menargetkan Space Anda.

Perhatikan bahwa `SPACE_HOST` [tersedia](https://huggingface.co/docs/hub/spaces-overview#built-in-environment-variables) sebagai variabel lingkungan.

Sebagai contoh, Anda dapat menggunakan `https://{SPACE_HOST}/login/callback` sebagai URI redirect.

## Cakupan

Scope berikut selalu disertakan untuk Spaces:

- `openid`: Menerima token ID di samping token akses.
- `profile`: Membaca informasi profil pengguna (nama pengguna, avatar, dll.)

Scope-scope tersebut bersifat opsional dan dapat ditambahkan dengan mengatur `hf_oauth_scopes` di metadata Space Anda:

- `email`: Membaca alamat email pengguna.
- `read-billing`: Mengetahui apakah pengguna telah mengatur metode pembayaran.
- `read-memberships`: Membaca organisasi mana yang menjadi anggota pengguna, dan peran mereka di masing-masing organisasi. Ini tidak memberikan akses ke pengaturan atau sumber daya organisasi.
- `read-repos`: Membaca repositori pribadi pengguna.
- `gated-repos`: Membaca konten repositori publik yang terkunci (gated) yang aksesnya telah diberikan kepada pengguna. Berbeda dengan `read-repos`, ini tidak memberikan akses ke repositori privat.
- `contribute-repos`: Membuat repositori dan mengakses repositori yang dibuat oleh aplikasi ini. Tidak dapat mengakses repositori lain kecuali izin tambahan diberikan.
- `write-repos`: Membaca dan menulis repositori pribadi pengguna.
- `manage-repos`: Kelola sepenuhnya repositori pribadi pengguna, termasuk membuat dan menghapusnya.
- `read-collections`: Membaca koleksi pribadi pengguna.
- `write-collections`: Membaca dan menulis koleksi pribadi pengguna, termasuk membuat dan menghapusnya.
- `inference-api`: Membuat permintaan inferensi ke [Inference Providers](https://huggingface.co/docs/inference-providers/index) atas nama pengguna.
- `read-endpoints`: Menampilkan [Inference Endpoints](https://huggingface.co/docs/inference-endpoints/index) milik pengguna dan membuat permintaan inferensi ke endpoint tersebut atas nama pengguna.
- `write-endpoints`: Mengelola Inference Endpoints pengguna, termasuk membuat dan menghapusnya. Termasuk akses `read-endpoints`.
- `jobs`: Jalankan [jobs](https://huggingface.co/docs/huggingface_hub/main/en/guides/jobs)
- `webhooks`: Kelola [webhooks](https://huggingface.co/docs/huggingface_hub/main/en/guides/webhooks)
- `write-discussions`: Membuka diskusi dan Pull Requests atas nama pengguna serta berinteraksi dengan diskusi (termasuk reaksi, memposting/mengedit komentar, menutup diskusi, ...). Untuk membuka Pull Requests pada repositori privat, Anda juga perlu meminta scope `read-repos`.

## Mengakses sumber daya organisasi

Secara default, aplikasi oauth tidak perlu mengakses sumber daya organisasi.

Namun beberapa scope seperti `read-repos` atau `read-billing` juga berlaku untuk organisasi.

Pengguna dapat memilih organisasi mana yang akan diberikan akses saat mengotorisasi aplikasi. Jika Anda memerlukan akses ke organisasi tertentu, Anda dapat menambahkan `orgIds=ORG_ID` sebagai parameter kueri ke URL otorisasi OAuth. Anda harus mengganti `ORG_ID` dengan ID organisasi, yang tersedia di field `organizations.sub` dari respons userinfo.

## Menambahkan tombol ke Space Anda

Anda kini memiliki semua informasi untuk menambahkan tombol "Sign-in with HF" ke Space Anda. Beberapa pustaka ([Python](https://github.com/lepture/authlib), [NodeJS](https://github.com/panva/node-openid-client)) dapat membantu Anda mengimplementasikan protokol OpenID/OAuth.

Gradio dan huggingface.js juga menyediakan **dukungan bawaan**, sehingga mengimplementasikan tombol Sign-in with HF menjadi sangat mudah; Anda dapat melihat panduan terkait dengan [gradio](https://www.gradio.app/guides/sharing-your-app#o-auth-login-via-hugging-face) dan dengan [huggingface.js](https://huggingface.co/docs/huggingface.js/hub/README#oauth-login).

Pada dasarnya, Anda perlu:

- Arahkan pengguna ke `https://huggingface.co/oauth/authorize?redirect_uri={REDIRECT_URI}&scope=openid%20profile&client_id={CLIENT_ID}&state={STATE}`, di mana `STATE` adalah string acak yang perlu Anda verifikasi kemudian.
- Atur callback di `/auth/callback` atau `/login/callback` (atau URL callback kustom Anda sendiri) dan verifikasi parameter `state`.
- Gunakan parameter query `code` untuk mendapatkan access token dan id token dari `https://huggingface.co/oauth/token` (permintaan POST dengan `client_id`, `code`, `grant_type=authorization_code` dan `redirect_uri` sebagai data formulir, serta `Authorization: Basic {base64(client_id:client_secret)}` sebagai header).

> [!WARNING]
> Anda harus menggunakan `target=_blank` pada tombol untuk membuka halaman masuk di tab baru, kecuali Anda menjalankan space di luar `iframe`-nya. Jika tidak, Anda mungkin akan mengalami masalah dengan cookie di beberapa browser.

## Contoh:

- [Aplikasi uji Gradio](https://huggingface.co/spaces/Wauplin/gradio-oauth-test)
- [HuggingChat (NodeJS/SvelteKit)](https://huggingface.co/spaces/huggingchat/chat-ui)
- [Widget Inferensi (Auth.js/SvelteKit)](https://huggingface.co/spaces/huggingfacejs/inference-widgets) menggunakan scope `inference-api` untuk membuat permintaan inferensi atas nama pengguna.
- [Di Sisi Klien dalam Ruang Statis (huggingface.js)](https://huggingface.co/spaces/huggingfacejs/client-side-oauth) - contoh JavaScript yang sangat sederhana.

Contoh kode 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);
```

