Space에 Sign-In with HF 버튼 추가

Space에 Sign-In with HF 버튼 추가

OAuth/OpenID connect 앱을 원활히 만들고 연결해 Space에 내장 로그인 흐름을 활성화할 수 있어요. 사용자가 HF 계정으로 로그인할 수 있게 되죠.

출처: 문서

본문

이렇게 하면 Space에 새로운 사용 사례가 생겨요. 예를 들어 Storage Buckets와 결합하면, 생성형 AI Space가 사용자가 이전 생성 결과에 접근하게 로그인을 요구할 수 있어요. 그 결과는 사용자만 접근할 수 있죠.

[!TIP] 이 가이드는 어떤 Space에도 Sign-In with HF 버튼을 통합하는 과정을 안내해요. Gradio Space에 빠르고 간단하게 구현하려면 내장 통합을 살펴보세요.

[!TIP] Spaces 밖의 어떤 웹사이트나 앱에서도 HF OAuth 흐름을 사용해 "Sign in with HF" 흐름을 만들 수 있어요. 일반 OAuth 페이지를 읽어보세요.

OAuth 앱 만들기

README.md 파일 안의 Space 메타데이터에 hf_oauth: true를 추가하기만 하면 돼요.

Gradio Space용 메타데이터 예시:

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

자세한 내용은 구성 레퍼런스 문서를 확인할 수 있어요.

이렇게 하면 Space에 다음 환경 변수가 추가돼요.

  • OAUTH_CLIENT_ID: OAuth 앱의 클라이언트 ID (공개)
  • OAUTH_CLIENT_SECRET: OAuth 앱의 클라이언트 시크릿
  • OAUTH_SCOPES: OAuth 앱이 접근할 수 있는 scope
  • OPENID_PROVIDER_URL: OpenID 프로바이더 URL. OpenID 메타데이터는 {OPENID_PROVIDER_URL}/.well-known/openid-configuration에서 확인할 수 있음

다른 환경 변수와 마찬가지로 코드에서 os.getenv("OAUTH_CLIENT_ID")처럼 사용할 수 있어요.

리다이렉트 URL

Space를 대상으로 하기만 하면 어떤 리다이렉트 URL이든 사용할 수 있어요.

SPACE_HOST환경 변수로 제공된다는 점을 기억하세요.

예를 들어 https://{SPACE_HOST}/login/callback을 리다이렉트 URI로 사용할 수 있어요.

Scopes

Spaces에는 다음 scope가 항상 포함돼요.

  • openid: 액세스 토큰에 더해 ID 토큰 수신
  • profile: 사용자 프로필 정보(사용자 이름, 아바타 등) 읽기

다음 scope는 선택적이고 Space 메타데이터에 hf_oauth_scopes를 설정해 추가할 수 있어요.

  • email: 사용자의 이메일 주소 읽기
  • read-billing: 사용자가 결제 수단을 설정했는지 알기
  • read-memberships: 사용자가 속한 조직과 각 조직에서의 역할 읽기. 조직의 설정이나 리소스에 접근 권한을 부여하지는 않음
  • read-repos: 사용자의 개인 저장소 읽기
  • gated-repos: 사용자가 접근 허가를 받은 공개 gated 저장소의 콘텐츠 읽기. read-repos와 달리 비공개 저장소에는 접근하지 못함
  • contribute-repos: 저장소를 만들고 이 앱이 만든 것에 접근. 추가 권한을 부여하지 않는 한 다른 저장소에는 접근 불가
  • write-repos: 사용자의 개인 저장소 읽기·쓰기
  • manage-repos: 사용자의 개인 저장소 완전 관리(생성·삭제 포함)
  • read-collections: 사용자의 개인 컬렉션 읽기
  • write-collections: 사용자의 개인 컬렉션 읽기·쓰기(생성·삭제 포함)
  • inference-api: 사용자를 대신해 Inference Providers에 추론 요청
  • read-endpoints: 사용자의 Inference Endpoints를 보고 사용자를 대신해 추론 요청
  • write-endpoints: 사용자의 Inference Endpoints 관리(생성·삭제 포함). read-endpoints 접근 포함
  • jobs: jobs 실행
  • webhooks: webhooks 관리
  • write-discussions: 사용자를 대신해 discussion과 Pull Request를 열고 상호작용(반응, 코멘트 게시/편집, discussion 닫기 등 포함). 비공개 저장소에서 Pull Request를 열려면 read-repos scope도 요청해야 함

조직 리소스 접근

기본적으로 oauth 앱은 조직 리소스에 접근할 필요가 없어요.

하지만 read-reposread-billing 같은 일부 scope는 조직에도 적용돼요.

사용자는 앱을 승인할 때 접근을 허용할 조직을 선택할 수 있어요. 특정 조직에 대한 접근이 필요하면 OAuth 승인 URL에 orgIds=ORG_ID를 쿼리 파라미터로 추가할 수 있어요. ORG_ID를 조직 ID로 바꿔야 하는데, 조직 ID는 userinfo 응답의 organizations.sub 필드에서 확인할 수 있어요.

Space에 버튼 추가

이제 Space에 "Sign-in with HF" 버튼을 추가할 모든 정보가 있게 됐어요. 일부 라이브러리(Python, NodeJS)가 OpenID/OAuth 프로토콜 구현을 도와줄 수 있어요.

Gradio와 huggingface.js도 내장 지원을 제공해 Sign-in with HF 버튼 구현을 아주 쉽게 만들어요. gradiohuggingface.js의 관련 가이드를 확인할 수 있어요.

기본적으로 해야 할 일:

  • 사용자를 https://huggingface.co/oauth/authorize?redirect_uri={REDIRECT_URI}&scope=openid%20profile&client_id={CLIENT_ID}&state={STATE}로 리다이렉트. 여기서 STATE는 나중에 검증해야 할 랜덤 문자열
  • /auth/callback 또는 /login/callback(또는 직접 만든 커스텀 콜백 URL)에서 콜백을 처리하고 state 파라미터를 검증
  • code 쿼리 파라미터로 https://huggingface.co/oauth/token에서 액세스 토큰과 ID 토큰을 얻음(client_id, code, grant_type=authorization_code, redirect_uri를 폼 데이터로, Authorization: Basic {base6...t)}를 헤더로 하는 POST 요청)

[!WARNING] Space를 iframe 밖에서 실행하지 않는 한 버튼에 target=_blank를 사용해 새 탭에서 로그인 페이지를 여는 게 좋아요. 그렇지 않으면 일부 브라우저에서 쿠키 문제가 발생할 수 있어요.

예시:

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

더 알아보기 (Learn more)

Space 메타데이터에 hf_oauth: true만 추가하면 OAuth 앱이 자동 생성되고 OAUTH_CLIENT_ID·OAUTH_CLIENT_SECRET·OAUTH_SCOPES 같은 환경 변수가 주입돼요. hf_oauth_scopes로 세분화된 권한을, hf_oauth_authorized_org로 조직 제한을 둘 수 있어요. 사용자를 /oauth/authorize로 리다이렉트하고 /oauth/token에서 코드로 토큰을 교환하면 돼요.