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-repos 或 read-billing 之类的 scope 同样适用于组织。

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

为 Space 添加登录按钮​

现在,你已经具备了在 Space 中添加 “Sign-in with HF” 登录按钮所需的全部信息。一些库(如 Python、NodeJS)可以帮助你实现 OpenID/OAuth 协议。

Gradio 和 huggingface.js 也提供了内置支持,使实现 “Sign-in with HF” 按钮变得非常简单;你可以查看对应的使用指南:gradio 和 huggingface.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_id、code、grant_type=authorization_code 和 redirect_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);