社交登录配置

在 Prism 中配置 OAuth 来源——内置提供商(GitHub、Google、Microsoft、Discord、Telegram、X、Cloudflare)以及自定义通用 OIDC / OAuth 2.0 提供商。

社交登录配置#

Prism 通过 OAuth 来源(OAuth Sources)支持社交登录——每个来源是一个独立命名的 OAuth 连接,拥有自己的 slug、凭据和显示名称。你可以添加同一提供商类型的多个来源(例如「GitHub(工作)」和「GitHub(个人)」),也可以使用通用 OIDC 或通用 OAuth 2 类型添加自定义提供商。

OAuth 来源在 Admin → OAuth Sources 中管理(不在 Settings 中)。每个来源有唯一的 slug,出现在其回调 URL 中:

https://<your-prism-domain>/api/connections/<slug>/callback

注意: Telegram 的登录流程与标准 OAuth 不同——它使用已验证的来源域名,而不是注册的回调 URL。上方的回调 URL 格式不适用于 Telegram。详见 Telegram 章节

内置提供商#

GitHub#

1. 创建 GitHub OAuth 应用#

  1. 前往 GitHub Developer Settings → OAuth Apps,点击 New OAuth App

  2. 填写表单:

    字段
    Application name你的站点名称
    Homepage URLhttps://your-prism-domain
    Authorization callback URLhttps://your-prism-domain/api/connections/<slug>/callback
  3. 点击 Register application

  4. 复制 Client ID

  5. 点击 Generate a new client secret 并立即复制——密钥仅显示一次。

2. 在 Prism 中添加来源#

前往 Admin → OAuth Sources → 添加来源

字段
Sluggithub(或任意唯一键)
提供商GitHub
显示名称GitHub(显示在登录按钮上)
Client ID从 GitHub 粘贴
Client Secret从 GitHub 粘贴

保存后,登录和注册页面会立即出现该按钮。

注意事项#

  • Prism 请求 user:email 权限范围,确保即使邮箱设为私密也能返回邮箱地址。

  • 如果 GitHub 用户没有公开邮箱且邮箱为私密,GitHub 返回邮箱列表——Prism 选取主要的已验证邮箱。

  • GitHub 不支持 OpenID Connect。Prism 使用其 REST API(/user/user/emails)。

Google#

1. 创建 Google OAuth 2.0 客户端#

  1. 打开 Google Cloud Console,选择或创建一个项目。

  2. 前往 APIs & Services → Credentials → Create Credentials → OAuth client ID

  3. 如果需要,先配置 OAuth 同意屏幕

    • 用户类型:External

    • 授权域名:你的 Prism 域名

    • 权限范围:openidemailprofile

  4. 填写 Create OAuth client ID

    字段
    Application typeWeb application
    Authorized JavaScript originshttps://your-prism-domain
    Authorized redirect URIshttps://your-prism-domain/api/connections/<slug>/callback
  5. 复制 Client IDClient Secret

2. 在 Prism 中添加来源#

前往 Admin → OAuth Sources → 添加来源,选择 提供商:Google,设置 slug(如 google),粘贴凭据。

注意事项#

  • Google 使用 OpenID Connect,Prism 请求 openid email profile

  • 新项目同意屏幕默认处于测试模式,仅允许已添加的测试用户登录。发布同意屏幕后,任意 Google 账号均可登录。

  • 未经验证的应用会显示警告屏幕,如预计有外部用户请提交验证。

Microsoft#

1. 注册 Azure AD 应用程序#

  1. 打开 Azure 门户 → 应用注册,点击 New registration

  2. 填写表单:

    字段
    Name你的站点名称
    Supported account typesAccounts in any organizational directory and personal Microsoft accounts
    Redirect URI平台选择 Webhttps://your-prism-domain/api/connections/<slug>/callback
  3. 点击 Register

  4. 从 Overview 页面复制 Application (client) ID

  5. 前往 Certificates & secrets → New client secret,复制 Value(不是 Secret ID)。

2. 在 Prism 中添加来源#

前往 Admin → OAuth Sources → 添加来源,选择 提供商:Microsoft,设置 slug(如 microsoft),粘贴凭据。

注意事项#

  • Prism 通过 common 租户端点请求 openid email profile,个人账号(Outlook/Hotmail)和工作/学校账号(Azure AD)均可登录。

  • 如需限制特定租户,调整 Supported account types 即可。

  • 客户端密钥会过期,请设置提醒在到期前轮换。

Discord#

1. 创建 Discord 应用程序#

  1. 打开 Discord Developer Portal,点击 New Application

  2. 前往 OAuth2 → General

    • 复制 Client ID

    • 点击 Reset Secret,确认后复制 Client Secret

    • Redirects 下添加:

      https://your-prism-domain/api/connections/<slug>/callback
      
  3. 保存更改。

2. 在 Prism 中添加来源#

前往 Admin → OAuth Sources → 添加来源,选择 提供商:Discord,设置 slug(如 discord),粘贴凭据。

注意事项#

  • Prism 请求 identify emailidentify 授予用户名和头像访问权限,email 授予已验证邮箱。

  • 如果 Discord 用户未设置邮箱,Prism 将拒绝登录。

  • Discord 不支持 OpenID Connect,Prism 使用 /users/@me

Telegram#

Telegram 使用基于小部件的身份验证流程,而非标准 OAuth。流程中没有授权码交换——用户在 Telegram 中确认登录后,其个人信息数据会以查询参数的形式直接发送至回调 URL,并附带由机器人令牌派生的 HMAC 签名。

1. 创建 Telegram 机器人#

  1. 打开与 @BotFather 的对话,运行 /newbot

  2. 按提示为机器人设置名称和用户名。

  3. BotFather 会给你一个格式为 123456789:ABCdef-GHIjkl...机器人令牌。复制它——这是 Prism 中的 Client Secret

  4. 冒号前的数字部分(如 123456789)是机器人 ID——这是 Prism 中的 Client ID

2. 注册域名#

Telegram 要求在允许登录前,先在 BotFather 中注册来源域名:

  1. 在同一个 BotFather 对话中,运行 /setdomain

  2. 选择你的机器人。

  3. 输入你的 Prism 域名(不含路径),例如 https://your-prism-domain

必须在 BotFather 中设置域名,再尝试 Telegram 登录。来自未注册来源域名的登录请求会因签名无效而失败。

3. 在 Prism 中添加来源#

前往 Admin → OAuth Sources → 添加来源

字段
Slugtelegram(或任意唯一键)
提供商Telegram
显示名称Telegram(显示在登录按钮上)
Client ID机器人数字 ID(令牌中 : 前的数字)
Client Secret完整机器人令牌(123456789:ABCdef...

保存后,登录和注册页面会立即出现该按钮。

注意事项#

  • Telegram 不提供邮箱地址。 通过 Telegram 注册的用户将使用占位邮箱(telegram_<id>@prism.local),且无法通过 Telegram 完成邮箱验证。用户注册后可在个人资料设置中添加并验证真实邮箱。

  • 身份验证数据中的时间戳(auth_date)会在服务器端验证——超过 24 小时的会话将被拒绝。

  • 与其他提供商不同,无需在提供商处注册回调 URL。Telegram 通过在 BotFather 中设置的来源域名进行路由,而非注册的重定向 URI。

X(Twitter)#

X 采用强制 PKCE 的 OAuth 2.0。Prism 会在每次授权请求中生成并发送 code_challenge,并通过 HTTP Basic 完成令牌交换——无需任何额外配置。

1. 创建 X OAuth 2.0 应用#

  1. 打开 X 开发者后台,选择(或创建)项目,并在其中新建 App

  2. 在应用的 User authentication settings 中点击 Set up(或 Edit):

    • App permissions:选择 Read 即可——Prism 仅读取资料。

    • Type of AppWeb App, Automated App or Bot(机密客户端,会下发 client secret)。

    • Callback URI / Redirect URLhttps://your-prism-domain/api/connections/<slug>/callback

    • Website URL:你的 Prism 域名

  3. 保存后在 Keys and tokens 标签的 OAuth 2.0 Client ID and Client Secret 区域复制 Client IDClient Secret(密钥只显示一次,遗失需重新生成)。

2. 在 Prism 中添加来源#

进入 Admin → OAuth Sources → Add source

字段
Slugx(或任意唯一键)
提供商X (Twitter)
显示名称X(显示在登录按钮上)
Client ID从 X 开发者后台复制
Client Secret从 X 开发者后台复制

保存后,登录页面会立即出现该按钮。

注意事项#

  • X v2 API 不返回邮箱。 通过 X 注册的用户将使用占位邮箱(x_<id>@prism.local),且初始状态为未验证——注册后可在个人资料设置中添加并验证真实邮箱。与 Telegram 流程一致。

  • Prism 请求的 scope 为 users.read tweet.read offline.access。其中 offline.access 是获取 refresh_token 的前提;缺失它时连接页的刷新按钮会要求用户重新授权。

  • Prism 调用 /2/users/me?user.fields=profile_image_url,name,username,并在写入前展开 v2 的 data 外层。

  • X 的令牌端点要求 HTTP Basic 认证,而非在请求体里附带 client_secret。Prism 在初次换码和刷新流程中已自动处理。

Cloudflare#

使用 Cloudflare 登录让用户以其 Cloudflare 账号进行认证——与 Wrangler 等工具代表用户操作账号所用的是同一套 OAuth 机制。Cloudflare 的 OAuth 客户端是API 访问客户端(其 scope 即 Cloudflare API 令牌权限名),并非 OpenID Connect 提供商。因此 Prism 在 https://dash.cloudflare.com/oauth2/{auth,token} 完成授权后,再从 Cloudflare API(GET https://api.cloudflare.com/client/v4/user)读取登录用户的身份。与其他内置提供商一样,你无需填写任何端点 URL。

不要请求 openid

Cloudflare 的自管理 OAuth 客户端无法请求 openid scope——权限范围选择器中根本没有该项,强行请求会在授权步骤报 invalid_scope(“The OAuth 2.0 Client is not allowed to request scope ‘openid’”)。Prism 改为请求 user-details.read(见下)。

1. 创建 Cloudflare OAuth 客户端#

  1. Cloudflare 控制台,进入 Manage Account → OAuth clients,点击 Create client

  2. 填写表单:

    字段
    客户端名称你的站点名称
    响应类型code
    授权类型authorization_code(需要令牌刷新时再加上 refresh_token
    令牌认证方式Client secret postclient_secret_post
    重定向 URLhttps://your-prism-domain/api/connections/<slug>/callback
  3. 在权限范围步骤,选择 User Details Readuser-details.read,位于 Account & Billing 分类下)——Prism 依靠它读取登录用户的身份。若启用了 refresh_token 授权,则同时添加 offline_access

  4. 点击 Create client,立即复制 Client IDClient Secret——密钥只显示一次。

2. 在 Prism 中添加来源#

进入 Admin → OAuth Sources → Add source

字段
Slugcloudflare(或任意唯一键)
提供商Cloudflare
显示名称Cloudflare(显示在登录按钮上)
Client ID从 Cloudflare 复制
Client Secret从 Cloudflare 复制

保存后,登录页面会立即出现该按钮。

注意事项#

  • Prism 请求的 scope 为 user-details.read offline_access,并从 GET /client/v4/user 读取身份,映射 id(提供商 ID)、first_name/last_name(显示名)与 username。Cloudflare 用户对象没有头像字段,因此不导入头像。

  • 邮箱: Cloudflare API 用户对象不含邮箱验证标记,Prism 无法确认该地址,因此不予信任。每次 Cloudflare 登录都会获得占位邮箱(cloudflare_<id>@prism.local)且初始未验证——之后可在个人资料设置中添加并验证真实邮箱。与 Telegram、X 流程一致。

  • 刷新令牌: 要让连接页的刷新按钮生效,OAuth 客户端必须启用 refresh_token 授权,且来源需保留 offline_access scope(Prism 默认发送)。否则 Cloudflare 不返回 refresh_token,用户须重新连接以续期。

  • 私有与公开客户端: 新建的 OAuth 客户端为私有——只有创建它的账号成员才能授权。要让任意 Cloudflare 用户登录,需完成 Cloudflare 的相关要求并将客户端可见性改为公开(此操作不可逆)。

  • 令牌端点接受 client_secret_post,因此你无需配置 PKCE 或 HTTP Basic。

通用 OpenID Connect#

使用提供商:通用 OpenID Connect 可接入任何符合 OIDC 标准的身份提供商(Keycloak、Okta、Auth0、Authentik、Zitadel 等)。

OIDC 自动发现(推荐)#

添加通用 OIDC 来源时,填写 Issuer URL 后点击自动发现按钮。Prism 会请求 {issuer}/.well-known/openid-configuration 并自动填充三个端点 URL。

字段
示例
Issuer URLhttps://accounts.example.com
授权 URL自动填充
令牌 URL自动填充
用户信息 URL自动填充

手动配置#

如果提供商不发布 discovery 文档,直接填写三个 URL:

字段
示例
授权 URLhttps://accounts.example.com/oauth2/authorize
令牌 URLhttps://accounts.example.com/oauth2/token
用户信息 URLhttps://accounts.example.com/oauth2/userinfo

权限范围#

Scopes 字段留空时默认为 openid email profile。如提供商需要不同的权限范围,填写以空格分隔的自定义列表。

用户信息映射#

Prism 使用标准 OIDC 声明映射用户信息:

Prism 字段
OIDC 声明
提供商 IDsub
显示名称namepreferred_username
用户名preferred_usernamesub
头像picture
邮箱email

回调 URL#

https://your-prism-domain/api/connections/<slug>/callback

在身份提供商的配置中将此 URL 添加为允许的重定向 URI。

通用 OAuth 2.0#

使用提供商:通用 OAuth 2 可接入符合 OAuth 2.0 但不完全符合 OIDC 标准的提供商(如 GitLab 自定义路径、Gitea、内部服务等)。

与通用 OIDC 不同,没有自动发现功能——三个端点 URL 均需手动填写。Prism 使用访问令牌调用用户信息端点,并尝试映射常见字段(sub/idname/login/usernamepicture/avatar_urlemail)。

同一提供商的多个来源#

每个来源拥有独立的 slug、Client ID 和 Client Secret,可以添加任意数量同类型来源:

Slug
提供商
显示名称
github-workGitHubGitHub(工作)
github-ossGitHubGitHub(个人)
googleGoogleGoogle
keycloak-devOIDC内部 SSO(开发)

所有已启用的来源将作为独立按钮显示在登录和注册页面。

流程安全#

每次登录都会设置一个有效期 10 分钟且带有 SecureHttpOnlySameSite=Lax 属性的关联 cookie。Prism 仅在 D1 中保存其哈希,并在回调时原子消费匹配的 state。复制到其他浏览器的回调 URL 会被拒绝,因为该浏览器没有发起流程时的 cookie。关联提供商还会额外绑定到发起流程的同一个有效 Prism 会话。登录成功后,Prism 通过干净的 /auth/callback URL 跳转,并且只用 HttpOnly Cookie 安装会话;会话 JWT 不会写入 URL,也不会返回给浏览器 JavaScript。

因此,完成社交登录期间必须允许 Prism 来源使用 cookie。如果回调显示 invalid_state,请在同一浏览器中重新开始流程,不要在不同浏览器或浏览器配置文件之间复制回调 URL。在同一浏览器中发起新的社交登录会取代仍在进行的旧流程。

本地开发#

本地测试时,使用 http://localhost:5173 作为域名注册 OAuth 应用,slug 与生产环境保持一致:

http://localhost:5173/api/connections/<slug>/callback

Google 和 Microsoft 要求生产环境使用 HTTPS,但允许开发环境使用 http://localhost。GitHub 和 Discord 也允许使用纯 HTTP 的 localhost URI。

Telegram 与本地开发

Telegram 要求来源域名使用 HTTPS,不支持 http://localhost。如需本地测试 Telegram 登录,需要一个公网 HTTPS 地址——可使用 cloudflared tunnel 或 ngrok 等内网穿透工具,并在 BotFather 中注册该地址(/setdomain)。

常见问题#

重定向 URI 不匹配 — 在提供商处注册的回调 URL 必须与来源 slug 完全一致(包括大小写)。检查 slug 和 APP_URLwrangler.jsonc)是否与注册时一致。

每次登录都创建新账号 — 社交关联通过 (source_slug, provider_user_id) 匹配。如果 slug 改变,旧关联会成为孤立记录。使用个人资料 → 关联账号重新关联。

首次社交登录时提示邮箱已被占用 — 如果已存在相同邮箱的账号(通过密码注册),Prism 会拒绝社交登录并报冲突错误。用户需先使用密码登录,然后在个人资料 → 关联账号中关联社交提供商。

Telegram:签名无效 — 身份验证数据的 HMAC 校验失败。通常原因是 Prism 中的 Client Secret 与机器人令牌不匹配,或来源域名尚未在 BotFather 中注册(/setdomain)。请检查这两项后重试。

Telegram:认证已过期 — Telegram 认证会话超过 24 小时。可能是用户长时间未完成认证流程。请让用户重新开始登录流程。

通用 OIDC 自动发现失败 — 确保 Issuer URL 使用 HTTPS,且提供商发布了 {issuer}/.well-known/openid-configuration。Worker 在服务端请求该文档(无 CORS 问题),但提供商不可达或响应慢会导致超时。