> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify-docs-automation-github-pr-review.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 认证设置

> 通过 OAuth、JWT、密码或 Mintlify Auth 配置站点的用户认证，以控制对页面和 API 参考的访问权限。

<Info>
  使用 Mintlify Auth 的认证适用于所有套餐。

  密码、OAuth 和 JWT 认证需要 [Enterprise 方案](https://mintlify.com/pricing?ref=authentication)。
</Info>

启用认证后，用户需先登录才能访问你的文档。

启用认证后，用户必须先登录才能访问任何内容。你可以将特定页面或分组配置为公开，而将其他页面设为受保护状态。

认证仅适用于托管在自定义域名或 Mintlify 子域名上的站点。例如，`docs.example.com` 或 `example.mintlify.site`。使用[自定义子路径](/zh/deploy/docs-subpath)的站点**不支持**认证。例如，`example.com/docs`。

<div id="configure-authentication">
  ## 配置认证
</div>

选择要配置的握手方式。

<Tabs>
  <Tab title="密码">
    <Info>
      密码认证仅提供访问控制，**不**支持用户级功能，例如基于用户组的访问控制或 API 操作台中的预填数据。
    </Info>

    ### 密码前提条件

    * 你的安全策略允许在多个用户之间共享密码。

    ### 密码设置

    <Steps>
      <Step title="创建密码。">
        1. 在控制台中，前往 [Authentication](https://dashboard.mintlify.com/products/authentication)。
        2. 在 **Authentication method** 部分，将站点可见性设置为 **Private**。
        3. 点击 **Password**。
        4. 输入一个安全的密码。
        5. 点击 **Save changes**。

        保存后，你的网站会重新部署。部署完成后，任何访问你站点的用户都必须输入该密码才能访问你的内容。
      </Step>

      <Step title="分发访问权限。">
        以安全方式将密码和文档 URL 分享给获授权的用户。
      </Step>
    </Steps>

    ### 密码示例

    你将文档托管在 `docs.foo.com`，只需要基础访问控制，而不需要跟踪单个用户。你希望阻止公众访问，同时保持设置简单。

    在控制台中**创建一个强密码**，并将**凭证分享**给获授权的用户。
  </Tab>

  <Tab title="Mintlify Auth">
    ### Mintlify Auth 前提条件

    * 所有需要访问你文档的人都必须是你 Mintlify 组织的成员。

    ### Mintlify Auth 设置

    <Steps>
      <Step title="在 Mintlify 控制台中启用认证。">
        1. 在控制台中，前往 [Authentication](https://dashboard.mintlify.com/products/authentication)。
        2. 在 **Authentication method** 部分，将站点可见性设置为 **Private**。
        3. 点击 **Authenticated**。
        4. 点击 **Save changes**。

        保存后，你的网站会重新部署。部署完成后，任何访问你网站的人都必须登录到你的 Mintlify 组织才能访问你的内容。
      </Step>

      <Step title="添加授权用户。">
        1. 在控制台中，前往 [Members](https://dashboard.mintlify.com/settings/organization/members)。
        2. 添加所有需要访问你文档的人员。
        3. 根据他们的编辑权限分配合适的角色。
      </Step>
    </Steps>

    ### Mintlify Auth 示例

    你将文档托管在 `docs.foo.com`，并且整个团队都能访问你的控制台。你希望仅将访问权限限制在团队成员。

    在控制台设置中**启用 Mintlify 认证**。

    通过检查所有团队成员在你的组织中是否为激活状态来**验证团队访问权限**。
  </Tab>

  <Tab title="OAuth 2.0">
    ### OAuth 2.0 前提条件

    * 支持 Authorization Code Flow (授权码流程) 的 OAuth 或 OIDC 服务器。
    * 能够创建可通过 OAuth 访问令牌访问的 API 端点 (可选，用于启用基于用户组的访问控制) 。

    ### OAuth 2.0 设置

    <Steps>
      <Step title="配置你的 OAuth 设置。">
        1. 在控制台中前往 [Authentication](https://dashboard.mintlify.com/products/authentication)。
        2. 在 **Authentication method** 部分，将站点可见性设置为 **Private**。
        3. 点击 **Custom**。
        4. 点击 **OAuth**。
        5. 配置以下字段：

        * **Authorization URL**：你的 OAuth 端点。
        * **Client ID**：你的 OAuth 2.0 客户端标识符。
        * **Client Secret**：你的 OAuth 2.0 客户端密钥。
        * **Scopes** (可选) ：要请求的权限。复制 **完整的** scope 字符串 (例如，对于 `provider.users.docs` 这样的 scope，复制完整的 `provider.users.docs`) 。如果需要不同的访问级别，可以使用多个 scope。
        * **Additional authorization parameters** (可选) ：要添加到初始授权请求中的其他 query 参数。
        * **Token URL**：你的 OAuth 令牌交换端点。
        * **Info API URL** (可选) ：你服务器上的一个端点，Mintlify 会调用它来获取用户信息。对于基于用户组的访问控制是必填项。如果省略，OAuth 流程只会验证身份。
        * **Logout URL** (可选) ：你的 OAuth 提供方自带的登出 URL。用户登出时，Mintlify 会将登出重定向与该配置的 URL 进行校验，以确保安全性。只有当重定向地址与配置的 `logoutUrl` 完全匹配时，重定向才会成功。如果你未配置登出 URL，用户会被重定向到 `/login`。Mintlify 会使用 `GET` 请求重定向用户，并且不会追加任何 query 参数，因此请将所有参数 (例如 `returnTo`) 直接包含在 URL 中。
        * **Redirect URL** (可选) ：在认证完成后重定向用户的 URL。

        6. 点击 **Save changes**。

        配置完 OAuth 设置后，你的网站会重新部署。部署完成后，任何访问你站点的用户都必须登录到你的 OAuth 提供方才能访问内容。
      </Step>

      <Step title="配置你的 OAuth 服务器。">
        1. 从你的[认证设置](https://dashboard.mintlify.com/products/authentication)中复制 **Redirect URL**。
        2. 将该 Redirect URL 添加为 OAuth 服务器中授权的重定向 URL。
      </Step>

      <Step title="创建用户信息端点（可选）。">
        为启用基于用户组的访问控制，创建一个 API 端点，该端点需满足：

        * 响应 `GET` 请求。
        * 接受 `Authorization: Bearer <access_token>` 头部用于认证。
        * 以 `User` 格式返回用户数据。更多信息参见 [User data format](#user-data-format)。

        Mintlify 使用 OAuth 访问令牌调用此端点以获取用户信息。不会发送额外的 query 参数。

        将此端点 URL 填入你[认证设置](https://dashboard.mintlify.com/products/authentication)中的 **Info API URL** 字段。
      </Step>
    </Steps>

    ### OAuth 2.0 示例

    你将文档托管在 `docs.foo.com`，并且你有一个现有的 OAuth 服务器 `auth.foo.com`，它支持 Authorization Code Flow。

    **在控制台中配置你的 OAuth 服务器详细信息**：

    * **Authorization URL**：`https://auth.foo.com/authorization`
    * **Client ID**：`ydybo4SD8PR73vzWWd6S0ObH`
    * **Scopes**：`['provider.users.docs']`
    * **Token URL**：`https://auth.foo.com/exchange`
    * **Info API URL**：`https://api.foo.com/docs/user-info`
    * **Logout URL**：`https://auth.foo.com/logout?returnTo=https%3A%2F%2Fdocs.foo.com`

    在 `api.foo.com/docs/user-info` 上**创建一个用户信息端点**，该端点要求使用带有 `provider.users.docs` scope 的 OAuth 访问令牌，并返回：

    ```json theme={null}
    {
      "groups": ["engineering", "admin"],
      "expiresAt": 1735689600,
      "apiPlaygroundInputs": {
        "header": {
          "Authorization": "Bearer user_abc123"
        }
      }
    }
    ```

    <Note>
      使用用户信息响应中的 `expiresAt` 字段控制会话时长。该字段为 Unix 时间戳 (自纪元以来的秒数) ，用于指示会话何时过期。更多详情请参阅 [用户数据格式](#user-data-format)。
    </Note>

    **将你的 OAuth 服务器配置为允许重定向**到回调 URL。
  </Tab>

  <Tab title="JWT（JSON Web Token）">
    ### JWT 前提条件

    * 一个可以生成并签名 JWT 的认证系统。
    * 一个可以创建重定向 URL 的后端服务。

    ### JWT 设置

    <Steps>
      <Step title="生成私钥。">
        1. 在控制台中前往 [Authentication](https://dashboard.mintlify.com/products/authentication)。
        2. 在 **Authentication method** 部分，将站点可见性设置为 **Private**。
        3. 点击 **Custom**。
        4. 点击 **JWT**。
        5. 输入你现有登录流程的 URL。
        6. 点击 **Save changes**。
        7. 点击 **Generate new key**。
        8. 将你的 key 安全存储在后端可以访问的位置。

        生成私钥后，你的网站会重新部署。部署完成后，任何访问你网站的人都必须登录到你的 JWT 认证系统才能访问你的内容。
      </Step>

      <Step title="将 Mintlify 认证集成到你的登录流程中。">
        修改你现有的登录流程，在用户通过认证后增加以下步骤：

        * 按 `User` 格式创建一个包含已认证用户信息的 JWT。更多信息参见 [User data format](#user-data-format)。
        * 使用 EdDSA 算法，用你的密钥对 JWT 进行签名。
        * 创建一个返回到文档 `/login/jwt-callback` 路径的重定向 URL，并将 JWT 放在 URL 片段 (hash) 中。
      </Step>
    </Steps>

    ### JWT 示例

    你在 `docs.foo.com` 上托管文档，并在 `foo.com` 上已有认证系统。你希望扩展登录流程，在保持文档与控制台分离的同时，为文档授予访问权限 (或者如果你没有控制台，则直接为文档授予访问权限) 。

    在 `https://foo.com/docs-login` 创建一个登录端点，用于扩展你现有的认证逻辑。

    在验证用户凭据之后：

    * 按 Mintlify 的格式生成包含用户数据的 JWT。
    * 对 JWT 进行签名并重定向到 `https://docs.foo.com/login/jwt-callback#{SIGNED_JWT}`。

    <CodeGroup>
      ```ts TypeScript theme={null}
      import * as jose from 'jose';
      import { Request, Response } from 'express';

      const TWO_WEEKS_IN_MS = 1000 * 60 * 60 * 24 * 7 * 2;
      const DOCS_HOST = 'docs.example.com';

      const signingKey = await jose.importPKCS8(process.env.MINTLIFY_PRIVATE_KEY, 'EdDSA');

      export async function handleRequest(req: Request, res: Response) {
        const user = {
          host: DOCS_HOST, // 必须与你的文档 URL 匹配
          expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000), // 2 周会话过期时间
          groups: res.locals.user.groups,
          apiPlaygroundInputs: {
            header: {
              "Authorization": `Bearer ${res.locals.user.apiKey}`,
            },
          },
        };

        const jwt = await new jose.SignJWT(user)
          .setProtectedHeader({ alg: 'EdDSA' })
          .setExpirationTime('10 s') // JWT 10 秒后过期
          .sign(signingKey);

        return res.redirect(`https://${DOCS_HOST}/login/jwt-callback#${jwt}`);
      }
      ```

      ```python Python theme={null}
      import jwt # pyjwt
      import os

      from datetime import datetime, timedelta
      from fastapi.responses import RedirectResponse

      private_key = os.getenv(MINTLIFY_JWT_PEM_SECRET_NAME, '')
      DOCS_HOST = 'docs.example.com'

      @router.get('/auth')
      async def return_mintlify_auth_status(current_user):
        jwt_token = jwt.encode(
          payload={
            'host': DOCS_HOST, # 必须与你的文档 URL 匹配
            'exp': int((datetime.now() + timedelta(seconds=10)).timestamp()),    # JWT 10 秒后过期
            'expiresAt': int((datetime.now() + timedelta(weeks=2)).timestamp()), # 2 周会话过期时间
            'groups': ['admin'] if current_user.is_admin else [],
            'apiPlaygroundInputs': {
              'header': {
                'Authorization': f'Bearer {current_user.api_key}',
              },
            },
          },
          key=private_key,
          algorithm='EdDSA'
        )

        return RedirectResponse(url=f'https://{DOCS_HOST}/login/jwt-callback#{jwt_token}', status_code=302)
      ```
    </CodeGroup>

    ### 重定向未认证用户

    当未认证用户尝试访问受保护页面时，系统在重定向到你的登录 URL 时会保留用户的目标地址。

    1. 用户尝试访问受保护页面：`https://docs.foo.com/quickstart`。
    2. 重定向到带有 redirect 查询参数的登录 URL：`https://foo.com/docs-login?redirect=%2Fquickstart`。
    3. 认证完成后，重定向到 `https://docs.foo.com/login/jwt-callback?redirect=%2Fquickstart#{SIGNED_JWT}`。
    4. 用户将进入其最初想要访问的页面。
  </Tab>
</Tabs>

<div id="make-pages-public">
  ## 公开页面
</div>

在使用认证时，所有页面默认都需要通过认证才能访问。你可以在页面或分组级别通过 `public` 属性将特定页面设置为无需认证即可访问。

<div id="individual-pages">
  ### 单个页面
</div>

要将页面设为公开，请在该页面的 frontmatter 中添加 `public: true`。

```mdx Public page example theme={null}
---
title: "公开页面"
public: true
---
```

<div id="groups-of-pages">
  ### 页面分组
</div>

要将某个分组中的所有页面设为公开，请在 `docs.json` 的 `navigation` 对象中，该分组名称下添加 `"public": true`。

```json Public group example theme={null}
{
  "navigation": {
    "groups": [
      {
        "group": "公开组",
        "public": true,
        "icon": "play",
        "pages": [
          "quickstart",
          "installation",
          "settings"
        ]
      },
      {
        "group": "私有组",
        "icon": "pause",
        "pages": [
          "private-information",
          "secret-settings"
        ]
      }
    ]
  }
}
```

<div id="control-access-with-groups">
  ## 使用 groups 控制访问
</div>

当你使用 OAuth 或 JWT (JSON Web Token) 进行认证时，可以将特定页面仅限于某些用户组访问。若希望不同用户根据其角色或属性查看不同内容，这将非常有用。

通过在认证过程中传递的用户数据来管理 groups。详见 [用户数据格式](#user-data-format)。

```json Example user info theme={null}
{
  "groups": ["admin", "beta-users"],
  "expiresAt": 1735689600
}
```

使用 frontmatter 中的 `groups` 属性来指定哪些 groups 可以访问特定页面。

```mdx Example page restricted to the admin group highlight={3} theme={null}
---
title: "管理员控制台"
groups: ["admin"]
---
```

用户必须至少属于所列的一个 groups 才能访问该页面。如果用户在不具备所需分组的情况下尝试访问页面，将会收到 404 错误。

<div id="how-groups-interact-with-public-pages">
  ### groups 如何与公共页面配合使用
</div>

* 默认情况下，所有页面都需要认证。
* 具有 `groups` 属性的页面仅对属于这些 groups 的已认证用户可访问。
* 没有 `groups` 属性的页面对所有已认证用户可访问。
* 具有 `public: true` 且没有 `groups` 属性的页面对所有人可访问。

<CodeGroup>
  ```mdx Public page theme={null}
  ---
  title: "Public guide"
  public: true
  ---
  ```

  ```mdx Protected page theme={null}
  ---
  title: "API reference"
  ---
  ```

  ```mdx Protected page with groups theme={null}
  ---
  title: "Advanced configurations"
  groups: ["pro", "enterprise"]
  ---
  ```
</CodeGroup>

<div id="user-data-format">
  ## 用户数据格式
</div>

当使用 OAuth 或 JWT 认证时，系统会返回用户数据，用于控制会话时长、基于用户组成员关系的访问控制，以及[内容个性化](/zh/create/personalization)。

<CodeGroup>
  ```tsx Format theme={null}
  type User = {
    host?: string;
    expiresAt?: number;
    groups?: string[];
    content?: Record<string, any>;
    apiPlaygroundInputs?: {
      server?: Record<string, string>;
      header?: Record<string, unknown>;
      query?: Record<string, unknown>;
      cookie?: Record<string, unknown>;
      path?: Record<string, unknown>;
    };
  };
  ```

  ```json Example theme={null}
  {
    "host": "docs.example.com",
    "expiresAt": 1735689600,
    "groups": ["admin", "beta-users"],
    "content": {
      "firstName": "Jane",
      "company": "Acme Corp"
    },
    "apiPlaygroundInputs": {
      "header": {
        "Authorization": "Bearer user_abc123"
      },
      "server": {
        "baseUrl": "https://api.foo.com"
      }
    }
  }
  ```
</CodeGroup>

<ParamField path="host" type="string">
  **JWT 认证时必填。** 你的文档站点的主机名。该字符串必须与你部署文档的 domain 完全一致。Mintlify 会验证 JWT 的 host 是否与发起请求的 host 匹配，以防止令牌在不同站点之间被重复使用。
</ParamField>

<ParamField path="expiresAt" type="number">
  会话过期时间，以自 epoch 起算的秒数表示。当当前时间超过该值时，用户必须重新完成认证。

  <Warning>**对于 JWT：** 这不同于 JWT 的 `exp` 声明，后者用于决定 JWT 何时被视为无效。出于安全考虑，应将 JWT 的 `exp` 声明设置为较短的时长 (10 秒或更少) 。使用 `expiresAt` 来表示实际会话时长 (从数小时到数周) 。</Warning>
</ParamField>

<ParamField path="groups" type="string[]">
  用户所属用户组的列表。frontmatter 中带有匹配 `groups` 的页面对该用户可访问。

  **示例**：具有 `groups: ["admin", "engineering"]` 的用户可以访问带有 `admin` 或 `engineering` 用户组标记的页面。
</ParamField>

<ParamField path="content" type="Record<string, any>">
  可在 MDX 页面中通过 `user` 变量访问的自定义数据，用于[个性化内容](/zh/create/personalization#dynamic-mdx-content)。
</ParamField>

<ParamField path="apiPlaygroundInputs" type="object">
  使用用户特定的值预填 API 操作台中的字段。当用户完成认证后，这些值会填充到 API 操作台中对应的输入字段。用户可以覆盖预填的值，其修改会持久保存在本地存储中。

  只有与当前端点的安全方案匹配的值才会被应用。

  <Expandable title="properties">
    <ParamField path="header" type="Record<string, unknown>">
      要预填的 Header 值，以 Header 名称作为 key。
    </ParamField>

    <ParamField path="query" type="Record<string, unknown>">
      要预填的查询参数值，以参数名称作为 key。
    </ParamField>

    <ParamField path="cookie" type="Record<string, unknown>">
      要预填的 Cookie 值，以 Cookie 名称作为 key。
    </ParamField>

    <ParamField path="server" type="Record<string, string>">
      要预填的服务器变量值，以变量名称作为 key。
    </ParamField>

    <ParamField path="path" type="Record<string, unknown>">
      要预填的路径参数值，以参数名称作为 key。
    </ParamField>
  </Expandable>
</ParamField>

<div id="feature-availability">
  ## 功能可用性
</div>

启用认证后，部分功能的行为会有所不同，或可能不可用。

| 功能                                                          | 公开   | 完全认证 (所有页面受保护)                 | 部分认证 (部分页面公开)                  |
| :---------------------------------------------------------- | :--- | :----------------------------- | :----------------------------- |
| [llms.txt 和 llms-full.txt](/zh/ai/llmstxt)                  | 完全支持 | 需要通过认证后才能访问，因此 AI 工具可能无法访问这些文件 | 可公开访问，仅反映公开页面                  |
| [MCP 服务器](/zh/ai/model-context-protocol)                    | 完全支持 | 连接时需要认证                        | 公开页面无需认证即可使用，受保护页面则需要认证        |
| [Markdown 导出](/zh/ai/markdown-export)                       | 完全支持 | 完全支持，尊重用户分组                    | 完全支持，尊重用户分组                    |
| [PDF 导出](/zh/optimize/pdf-exports)                          | 完全支持 | 完全支持，尊重用户分组。已认证页面在导出时会包含图片和资源。 | 完全支持，尊重用户分组。已认证页面在导出时会包含图片和资源。 |
| [搜索](/zh/assistant/index)                                   | 完全支持 | 完全支持，尊重用户分组                    | 完全支持，尊重用户分组                    |
| [AI 助手](/zh/assistant/index)                                | 完全支持 | 完全支持，尊重用户分组                    | 完全支持，尊重用户分组                    |
| [skill.md](/zh/ai/skillmd)                                  | 完全支持 | 不支持                            | 不支持                            |
| [站点地图](/zh/optimize/seo#sitemaps-and-robotstxt-files)       | 完全支持 | 需要通过认证后才能访问，但会排除 groups 中的页面   | 需要通过认证后才能访问，但会排除 groups 中的页面   |
| [robots.txt](/zh/optimize/seo#sitemaps-and-robotstxt-files) | 完全支持 | 需要通过认证后才能访问                    | 需要通过认证后才能访问                    |
