跳转到主要内容
FIM One 支持通过 GitHub、Google、Discord 和 Feishu(Lark)进行社交登录。任何在环境中存在凭证的提供商都会在登录页面上自动显示登录按钮 — 无需更改代码。 回调 URL 模式 — 在每个提供商的开发者控制台中注册此确切 URL:
{API_BASE_URL}/api/auth/oauth/{provider}/callback
API_BASE_URL 是 FIM One 后端的外部可访问地址。示例:
场景示例回调 URL
本地开发http://localhost:8000/api/auth/oauth/github/callback
专用 API 子域https://api.yourdomain.com/api/auth/oauth/github/callback
反向代理(同一域)https://yourdomain.com/api/auth/oauth/github/callback

GitHub

开发者控制台: https://github.com/settings/developers
  1. 点击 OAuth AppsNew OAuth App
  2. 填写:
    • Application name — 任意名称(例如 FIM One
    • Homepage URL — 你的前端 URL(例如 https://yourdomain.com
    • Authorization callback URLhttps://yourdomain.com/api/auth/oauth/github/callback
  3. 点击 Register application,然后点击 Generate a new client secret
  4. Client ID 和生成的 Client Secret 复制到你的 .env
自动请求的作用域: read:user, user:email 具有私密主要邮箱的 GitHub 账户处理正确 — FIM One 始终从 /user/emails 获取主要验证邮箱,而不是公开资料邮箱。
GITHUB_CLIENT_ID=Ov23li...
GITHUB_CLIENT_SECRET=...

Google

开发者控制台: https://console.cloud.google.com/apis/credentials
  1. 点击 + CREATE CREDENTIALSOAuth client ID
  2. 如果出现提示,先配置 OAuth consent screen(将 User Type 设置为”External”以用于个人/公共应用)。
  3. Application type 设置为 Web application
  4. Authorized redirect URIs 下,添加:
    https://yourdomain.com/api/auth/oauth/google/callback
    
  5. 点击 Create,然后复制 Client IDClient Secret
自动请求的作用域: openid, email, profile
注意:在开发期间,同意屏幕将显示”This app is not verified”警告。您可以继续通过它进行测试。如果要为最终用户移除该警告,请发布同意屏幕。
GOOGLE_CLIENT_ID=12345678-abc.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-...

Discord

开发者控制台: https://discord.com/developers/applications
  1. 点击 New Application 并给它命名。
  2. 在左侧边栏中,点击 OAuth2
  3. Redirects 下,点击 Add Redirect 并输入:
    https://api.yourdomain.com/api/auth/oauth/discord/callback
    
  4. 复制 Client ID(显示在 OAuth2 页面顶部)并点击 Reset Secret 以显示 Client Secret
自动请求的作用域: identify, email
Discord 不保证所有账户都有已验证的电子邮件。如果用户未向 Discord 验证其电子邮件,email 字段可能为 null。FIM One 在这种情况下会使用 null 电子邮件创建账户 — 用户可以稍后在设置中添加。
DISCORD_CLIENT_ID=123456789012345678
DISCORD_CLIENT_SECRET=...

飞书 (Lark)

仅限租户范围。 飞书自建应用只能对创建该应用的同一企业租户内的用户进行身份验证。来自其他飞书租户的用户将看到”无权限”错误。这意味着飞书 OAuth 不适合公共 SaaS 部署,其中用户来自不同的组织。它适用于私有/单组织部署,其中所有用户属于同一飞书租户。要支持跨租户飞书登录,您需要将应用发布到飞书应用商店并通过飞书的审核流程——这很复杂且要求严格。
开发者控制台: https://open.feishu.cn/app
  1. 点击创建应用自建应用。需要公司/企业账户——飞书 OAuth 不适用于个人账户。
  2. 权限与范围下,搜索并启用:
    • contact:user.email:readonly
  3. 安全设置重定向 URL 下,添加您的回调 URL:
    https://yourdomain.com/api/auth/oauth/feishu/callback
    
  4. 凭证与基本信息部分复制 App IDApp Secret
在控制台中配置的范围(不在授权 URL 中): contact:user.email:readonly
注意:飞书使用 App ID / App Secret 而不是标准的 Client ID / Client Secret 命名。环境变量名称反映了这一点:FEISHU_APP_IDFEISHU_APP_SECRET
FEISHU_APP_ID=cli_a1b2c3d4e5f6...
FEISHU_APP_SECRET=...

重要:飞书邮箱行为

飞书用户信息 API (authen/v1/user_info) 返回用户的企业联系邮箱 (联系邮箱) — 由组织管理员在飞书管理后台配置的地址。这不是用户的个人飞书登录邮箱。 后果:
  • 组织管理员未配置联系邮箱的用户将从 API 获得空的邮箱字段,即使他们拥有有效的飞书账户。
  • 个人飞书账户用户(不属于企业)将始终获得空的邮箱。
FIM One 可以优雅地处理这种情况:参见下面的账户绑定规则

账户绑定规则

注册用户可以从设置 → 账户链接其他 OAuth 提供商。当用户启动绑定时,以下规则适用:

通用规则(GitHub、Google、Discord)

OAuth 提供商返回的电子邮件必须与 FIM 账户注册的电子邮件相匹配。这可以防止意外将他人的社交账户关联到您的 FIM 账户。 如果电子邮件不匹配,绑定将被拒绝,并返回 email_mismatch 错误。

飞书异常

由于飞书的 API 返回企业联系邮箱而非登录邮箱,且该字段对于个人账户或管理员未配置的组织中的账户通常为空,飞书的邮箱匹配检查遵循更宽松的规则:
  • 双方都有邮箱 → 邮箱必须匹配(与其他提供商的检查相同)。
  • 任一方没有邮箱(飞书返回空值,或 FIM 账户没有邮箱)→ 仅基于票证身份验证成功绑定。

Feishu 登录(尚未绑定)

当用户首次通过 Feishu 登录时(没有现有绑定):
  1. FIM One 查找现有账户,其电子邮件与 Feishu 企业联系人电子邮件匹配。
  2. 如果找到匹配项,Feishu 账户会自动绑定到该现有 FIM 账户,用户随即登录。
  3. 如果没有匹配项(包括电子邮件为空的情况),会创建一个由 Feishu open_id 标识的新 FIM 账户。该账户的电子邮件为空,用户可以稍后从设置中填写。

环境变量快速参考

变量提供商必需描述
GITHUB_CLIENT_IDGitHubBothGitHub OAuth App 客户端 ID
GITHUB_CLIENT_SECRETGitHubBothGitHub OAuth App 客户端密钥
GOOGLE_CLIENT_IDGoogleBothGoogle OAuth 2.0 客户端 ID
GOOGLE_CLIENT_SECRETGoogleBothGoogle OAuth 2.0 客户端密钥
DISCORD_CLIENT_IDDiscordBothDiscord OAuth2 应用客户端 ID
DISCORD_CLIENT_SECRETDiscordBothDiscord OAuth2 应用客户端密钥
FEISHU_APP_IDFeishuBothFeishu 内部应用 ID(注意:不是 CLIENT_ID
FEISHU_APP_SECRETFeishuBothFeishu 内部应用密钥
FRONTEND_URLAllProdOAuth 完成后浏览器重定向的位置(例如 https://yourdomain.com
API_BASE_URLAllProd外部可访问的后端 URL,用于构建回调 URL
NEXT_PUBLIC_API_URLAllProd浏览器端 API URL 用于 OAuth 重定向 — 在构建时嵌入
“必需: Both” 表示 _ID_SECRET(或 Feishu 的 _APP_ID_APP_SECRET)必须一起设置;仅设置其中一个无效。
查看环境变量了解 FRONTEND_URLAPI_BASE_URLNEXT_PUBLIC_API_URL 的完整文档。