Skip to main content

为你的 Space 添加 “Sign-In with HF” 按钮

你可以在 Space 中启用内置的登录流程:通过创建并关联一个 OAuth/OpenID Connect 应用,让用户使用自己的 HF 账号登录你的 Space。

这样可以为你的 Space 解锁更多用例。例如,结合 Persistent Storage,一个生成式 AI 的 Space 就可以让用户登录后访问自己以前的生成记录,而且这些记录仅对该用户可见。

tip

本指南会带你逐步在任意 Space 中集成 Sign-In with HF 登录按钮。如果你只是在 Gradio Space 中需要一个快速简单的方案,可以直接参考 Gradio 的内置集成

tip

你也可以在 Spaces 之外,使用 HF OAuth 流程,在任意网站或 App 上实现 “Sign in with HF” 登录。详见通用 OAuth 页面

创建 OAuth 应用

你只需要在 Space 仓库的 README.md 元数据中加上 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
# 可选,默认持续时间为 8 小时/480 分钟。最大持续时间为 30 天/43200 分钟。
hf_oauth_expiration_minutes: 480
# 可选,请参阅下面的 "Scopes"。"openid profile" 始终包含。
hf_oauth_scopes:
- read-repos
- write-repos
- manage-repos
- inference-api
# 可选,限制访问特定组织的成员
hf_oauth_authorized_org: ORG_NAME
hf_oauth_authorized_org:
- ORG_NAME1
- ORG_NAME2

你可以查看 配置参考文档 获取更多信息。

这会为你的 Space 添加以下环境变量

  • OAUTH_CLIENT_ID:OAuth 应用的 client ID(公开)
  • OAUTH_CLIENT_SECRET:OAuth 应用的 client secret
  • OAUTH_SCOPES:OAuth 应用可以访问的作用域(scope)
  • OPENID_PROVIDER_URL:OpenID 提供方的 URL。OpenID 元数据会暴露在 {OPENID_PROVIDER_URL}/.well-known/openid-configuration

和其它环境变量一样,你可以在代码中通过 os.getenv("OAUTH_CLIENT_ID") 等方式访问这些值。

重定向 URL

只要重定向地址最终指向你的 Space,你可以选择任意 redirect URL。

注意,SPACE_HOST 也会作为辅助环境变量提供。

例如,你可以将 https://{SPACE_HOST}/login/callback 用作 redirect URI。

作用域(Scopes)

对于启用 OAuth 的 Space,以下 scopes 会始终被默认包含:

  • openid:在 access token 之外再获取 ID token。
  • profile:获取用户的基本资料(用户名、头像等)。

下面这些 scopes 是可选的,你可以通过在 Space 的元数据中设置 hf_oauth_scopes 来添加:

  • email:获取用户的邮箱地址。
  • read-billing:了解用户是否已配置付款方式。
  • read-repos:对用户个人仓库的只读访问权限。
  • contribute-repos:可以创建仓库并访问由该应用创建的仓库。除非获得额外权限,否则无法访问其它仓库。
  • write-repos:对用户个人仓库的读写访问权限。
  • manage-repos:对用户个人仓库的完全访问权限,包括创建和删除仓库。
  • inference-api:访问 Inference Providers,代表用户发起推理请求。
  • jobs:运行 jobs
  • webhooks:管理 webhooks
  • write-discussions:代表用户创建讨论和 Pull Request,并与讨论交互(点赞、评论/编辑、关闭讨论等)。如果需要在私有仓库中开启 Pull Request,还需要额外申请 read-repos scope。

访问组织资源

默认情况下,OAuth 应用不需要访问组织资源。

但诸如 read-reposread-billing 之类的 scope 同样适用于组织。

用户在授权应用时,可以选择授予哪些组织的访问权限。如果你需要访问某个特定组织,可以在 OAuth 授权 URL 上添加 orgIds=ORG_ID 查询参数。这里的 ORG_ID 是组织 ID,可以从 userinfo 响应中的 organizations.sub 字段中获取。

为 Space 添加登录按钮

现在,你已经具备了在 Space 中添加 “Sign-in with HF” 登录按钮所需的全部信息。一些库(如 PythonNodeJS)可以帮助你实现 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 参数。
  • 使用回调 URL 中的 code 参数,从 https://huggingface.co/oauth/token 获取 access token 和 id token(向该地址发送 POST 请求,表单数据中包含 client_idcodegrant_type=authorization_coderedirect_uri,同时在 Header 中加入 Authorization: Basic {base64(client_id:client_secret)})。
warning

除非你的 Space 不在 iframe 中运行,否则建议在登录按钮上使用 target=_blank,将登录页在新标签页中打开,否则在部分浏览器上可能遇到 cookie 相关问题。

示例:

JS 代码示例:

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

const oauthResult = await oauthHandleRedirectIfPresent();

if (!oauthResult) {
// 如果用户未登录,重定向到登录页面
window.location.href = await oauthLoginUrl();
}

// 你可以使用 oauthResult.accessToken, oauthResult.userInfo 等其他信息
console.log(oauthResult);