> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fim.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 提供商

> 配置 GitHub、Google、Discord 和 Feishu 社交登录。

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](https://github.com/settings/developers)

1. 点击 **OAuth Apps** → **New OAuth App**。
2. 填写：
   * **Application name** — 任意名称（例如 `FIM One`）
   * **Homepage URL** — 你的前端 URL（例如 `https://yourdomain.com`）
   * **Authorization callback URL** — `https://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` 获取主要验证邮箱，而不是公开资料邮箱。

```env theme={null}
GITHUB_CLIENT_ID=Ov23li...
GITHUB_CLIENT_SECRET=...
```

***

## Google

**开发者控制台:** [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)

1. 点击 **+ CREATE CREDENTIALS** → **OAuth 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 ID** 和 **Client Secret**。

**自动请求的作用域:** `openid`, `email`, `profile`

> 注意：在开发期间，同意屏幕将显示"This app is not verified"警告。您可以继续通过它进行测试。如果要为最终用户移除该警告，请发布同意屏幕。

```env theme={null}
GOOGLE_CLIENT_ID=12345678-abc.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-...
```

***

## Discord

**开发者控制台:** [https://discord.com/developers/applications](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 电子邮件创建账户 — 用户可以稍后在设置中添加。

```env theme={null}
DISCORD_CLIENT_ID=123456789012345678
DISCORD_CLIENT_SECRET=...
```

***

## 飞书 (Lark)

<Warning>
  **仅限租户范围。** 飞书自建应用只能对创建该应用的**同一企业租户内**的用户进行身份验证。来自其他飞书租户的用户将看到"无权限"错误。这意味着飞书 OAuth **不适合公共 SaaS 部署**，其中用户来自不同的组织。它适用于**私有/单组织部署**，其中所有用户属于同一飞书租户。

  要支持跨租户飞书登录，您需要将应用发布到[飞书应用商店](https://open.feishu.cn/document/store-v1/overview)并通过飞书的审核流程——这很复杂且要求严格。
</Warning>

**开发者控制台：** [https://open.feishu.cn/app](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 ID** 和 **App Secret**。

**在控制台中配置的范围（不在授权 URL 中）：** `contact:user.email:readonly`

> 注意：飞书使用 `App ID` / `App Secret` 而不是标准的 `Client ID` / `Client Secret` 命名。环境变量名称反映了这一点：`FEISHU_APP_ID` 和 `FEISHU_APP_SECRET`。

```env theme={null}
FEISHU_APP_ID=cli_a1b2c3d4e5f6...
FEISHU_APP_SECRET=...
```

### 重要：飞书邮箱行为

飞书用户信息 API (`authen/v1/user_info`) 返回用户的**企业联系邮箱** (联系邮箱) — 由组织管理员在飞书管理后台配置的地址。这**不是**用户的个人飞书登录邮箱。

后果：

* 组织管理员未配置联系邮箱的用户将从 API 获得空的邮箱字段，即使他们拥有有效的飞书账户。
* 个人飞书账户用户（不属于企业）将始终获得空的邮箱。

FIM One 可以优雅地处理这种情况：参见下面的[账户绑定规则](#account-binding-rules)。

***

## 账户绑定规则

注册用户可以从**设置 → 账户**链接其他 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_ID`      | GitHub  | Both | GitHub OAuth App 客户端 ID                         |
| `GITHUB_CLIENT_SECRET`  | GitHub  | Both | GitHub OAuth App 客户端密钥                          |
| `GOOGLE_CLIENT_ID`      | Google  | Both | Google OAuth 2.0 客户端 ID                         |
| `GOOGLE_CLIENT_SECRET`  | Google  | Both | Google OAuth 2.0 客户端密钥                          |
| `DISCORD_CLIENT_ID`     | Discord | Both | Discord OAuth2 应用客户端 ID                         |
| `DISCORD_CLIENT_SECRET` | Discord | Both | Discord OAuth2 应用客户端密钥                          |
| `FEISHU_APP_ID`         | Feishu  | Both | Feishu 内部应用 ID（注意：不是 `CLIENT_ID`）               |
| `FEISHU_APP_SECRET`     | Feishu  | Both | Feishu 内部应用密钥                                   |
| `FRONTEND_URL`          | All     | Prod | OAuth 完成后浏览器重定向的位置（例如 `https://yourdomain.com`） |
| `API_BASE_URL`          | All     | Prod | 外部可访问的后端 URL，用于构建回调 URL                         |
| `NEXT_PUBLIC_API_URL`   | All     | Prod | 浏览器端 API URL 用于 OAuth 重定向 — 在构建时嵌入              |

"必需: Both" 表示 `_ID` 和 `_SECRET`（或 Feishu 的 `_APP_ID` 和 `_APP_SECRET`）必须一起设置；仅设置其中一个无效。

> 查看[环境变量](/configuration/environment-variables)了解 `FRONTEND_URL`、`API_BASE_URL` 和 `NEXT_PUBLIC_API_URL` 的完整文档。
