mirror of
https://github.com/mintlify/docs.git
synced 2026-09-14 13:35:46 +08:00
bbb1a08ed3
Co-authored-by: locadex-agent[bot] <217277504+locadex-agent[bot]@users.noreply.github.com>
388 lines
14 KiB
Plaintext
388 lines
14 KiB
Plaintext
---
|
||
title: "认证设置"
|
||
description: "通过用户认证来控制对文档的访问。"
|
||
keywords: ['authentication', 'auth', 'OAuth', 'JWT', 'password']
|
||
---
|
||
|
||
<Info>
|
||
[Pro 方案](https://mintlify.com/pricing?ref=authentication) 包含密码认证。
|
||
|
||
[Custom 方案](https://mintlify.com/pricing?ref=authentication) 包含所有认证方式。
|
||
</Info>
|
||
|
||
启用认证后,用户需先登录才能访问你的文档。
|
||
|
||
<div id="authentication-modes">
|
||
## 认证模式
|
||
</div>
|
||
|
||
根据你的访问控制需求,在完整认证和部分认证模式之间进行选择。
|
||
|
||
**完整认证**:所有页面均受保护。用户必须先登录才能访问任何内容。
|
||
|
||
**部分认证**:部分页面可公开查看,其他页面需要认证。用户可以自由浏览公开内容,访问受保护页面时再进行认证。
|
||
|
||
在配置下方任一握手机制时,你需要在控制台设置中选择 **完整认证** 或 **部分认证**。
|
||
|
||
<div id="configure-authentication">
|
||
## 配置认证
|
||
</div>
|
||
|
||
选择要配置的握手方式。
|
||
|
||
<Tabs>
|
||
<Tab title="密码">
|
||
<Info>
|
||
密码认证仅提供访问控制,且**不**支持内容个性化。
|
||
</Info>
|
||
|
||
### 前提条件
|
||
|
||
* 你的安全策略允许在用户之间共享密码。
|
||
|
||
### 实施
|
||
|
||
<Steps>
|
||
<Step title="创建密码。">
|
||
1. 在你的控制台,前往 [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication)。
|
||
2. 选择 **Full Authentication** 或 **Partial Authentication**。
|
||
3. 选择 **Password**。
|
||
4. 输入一个强密码。
|
||
5. 选择 **保存更改**。
|
||
</Step>
|
||
|
||
<Step title="分发访问。">
|
||
将密码和文档站点的 URL 安全地分享给获授权的用户。
|
||
</Step>
|
||
</Steps>
|
||
|
||
### 示例
|
||
|
||
你的文档托管在 `docs.foo.com`,你需要基本的访问控制,但不跟踪单个用户。你想阻止公众访问,同时保持设置简单。
|
||
|
||
在控制台中**创建一个强密码**,并将**凭证**分享给获授权的用户。就这样!
|
||
</Tab>
|
||
|
||
<Tab title="Mintlify 控制台">
|
||
### 先决条件
|
||
|
||
* 所有需要访问你文档的人都必须是你 Mintlify 组织的成员。
|
||
|
||
### 实施
|
||
|
||
<Steps>
|
||
<Step title="启用 Mintlify 控制台认证。">
|
||
1. 在控制台中,前往 [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication)。
|
||
2. 选择 **Full Authentication** 或 **Partial Authentication**。
|
||
3. 选择 **Mintlify Auth**。
|
||
4. 选择 **Enable Mintlify Auth**。
|
||
</Step>
|
||
|
||
<Step title="添加授权用户。">
|
||
1. 在控制台中,前往 [Members](https://dashboard.mintlify.com/settings/organization/members)。
|
||
2. 将每位需要访问你文档的人添加为成员。
|
||
3. 根据其编辑权限分配合适的角色。
|
||
</Step>
|
||
</Steps>
|
||
|
||
### 示例
|
||
|
||
你的文档托管在 `docs.foo.com`,且你的整个团队都可访问控制台。你希望仅限团队成员访问。
|
||
|
||
在控制台设置中**启用 Mintlify 认证**。
|
||
|
||
通过确认所有团队成员都已添加到你的组织来**验证团队访问权限**。
|
||
</Tab>
|
||
|
||
<Tab title="OAuth 2.0">
|
||
### 先决条件
|
||
|
||
* 支持 Authorization Code Flow 的 OAuth 或 OIDC 服务器。
|
||
* 具备创建可通过 OAuth 访问令牌访问的 API 端点的能力(可选,用于启用个性化功能)。
|
||
|
||
### 实施
|
||
|
||
<Steps>
|
||
<Step title="配置你的 OAuth 设置。">
|
||
1. 在控制台中前往 [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication)。
|
||
2. 选择 **Full Authentication** 或 **Partial Authentication**。
|
||
3. 选择 **OAuth** 并配置以下字段:
|
||
|
||
* **Authorization URL**:你的 OAuth 授权端点。
|
||
* **Client ID**:你的 OAuth 2.0 客户端标识符。
|
||
* **Client Secret**:你的 OAuth 2.0 客户端密钥。
|
||
* **Scopes**:要请求的权限。复制**完整**的 scope 字符串(例如,对于 `provider.users.docs` 这样的 scope,请复制完整的 `provider.users.docs`)。如需不同的访问级别,可使用多个 scopes。
|
||
* **Token URL**:你的 OAuth 令牌交换端点。
|
||
* **Info API URL**(可选):你服务器上的端点,Mintlify 会调用该端点以获取用于个性化的用户信息。若留空,OAuth 流程仅用于身份验证,用户信息将为空。
|
||
* **Logout URL**:你的 OAuth 提供商的原生登出 URL。若提供商支持 `returnTo` 或类似参数,请将其指回你的文档 URL。
|
||
|
||
4. 选择 **Save changes**。
|
||
</Step>
|
||
|
||
<Step title="配置你的 OAuth 服务器。">
|
||
1. 从你的[认证设置](https://dashboard.mintlify.com/settings/deployment/authentication)中复制 **Redirect URL**。
|
||
2. 将该重定向 URL 添加为你的 OAuth 服务器的已授权重定向 URL。
|
||
</Step>
|
||
|
||
<Step title="创建你的用户信息端点(可选)。">
|
||
若要启用个性化功能,请创建一个 API 端点,该端点:
|
||
|
||
* 接受 OAuth 访问令牌进行认证。
|
||
* 按 `User` 格式返回用户数据。更多信息参见 [User data format](/zh/deploy/personalization-setup#user-data-format)。
|
||
|
||
将此端点的 URL 填入你的[认证设置](https://dashboard.mintlify.com/settings/deployment/authentication)中的 **Info API URL** 字段。
|
||
</Step>
|
||
</Steps>
|
||
|
||
### 示例
|
||
|
||
你的文档托管在 `foo.com/docs`,并且你在 `auth.foo.com` 上已有一个支持 Authorization Code Flow 的 OAuth 服务器。
|
||
|
||
在控制台中**配置 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%2Ffoo.com%2Fdocs`
|
||
|
||
在 `api.foo.com/docs/user-info` **创建一个用户信息端点**,该端点需要具有 `provider.users.docs` scope 的 OAuth 访问令牌,并返回:
|
||
|
||
```json
|
||
{
|
||
"content": {
|
||
"firstName": "Jane",
|
||
"lastName": "Doe"
|
||
},
|
||
"groups": ["engineering", "admin"]
|
||
}
|
||
```
|
||
|
||
**将你的 OAuth 服务器配置为允许重定向**到你的回调 URL。
|
||
</Tab>
|
||
|
||
<Tab title="JWT(JSON Web Token)">
|
||
### 先决条件
|
||
|
||
* 一个可以生成并签署 JWT 的认证系统。
|
||
* 一个可以创建重定向 URL 的后端服务。
|
||
|
||
### 实施
|
||
|
||
<Steps>
|
||
<Step title="生成私钥。">
|
||
1. 在你的控制台,前往 [认证](https://dashboard.mintlify.com/settings/deployment/authentication)。
|
||
2. 选择 **完全认证(Full Authentication)** 或 **部分认证(Partial Authentication)**。
|
||
3. 选择 **JWT**。
|
||
4. 输入你现有登录流程的 URL,并选择 **保存更改(Save changes)**。
|
||
5. 选择 **生成新 key(Generate new key)**。
|
||
6. 将你的 key 安全存储在后端可访问的位置。
|
||
</Step>
|
||
|
||
<Step title="将 Mintlify 认证集成到你的登录流程中。">
|
||
在用户通过认证后,修改你现有的登录流程以包含以下步骤:
|
||
|
||
* 创建一个包含已认证用户信息的 JWT,采用 `User` 格式。更多信息参见[用户数据格式](/zh/deploy/personalization-setup#user-data-format)。
|
||
* 使用你的私钥并采用 EdDSA 算法对 JWT 进行签名。
|
||
* 创建一个返回到文档 `/login/jwt-callback` 路径的重定向 URL,并将 JWT 作为 hash 附加其后。
|
||
</Step>
|
||
</Steps>
|
||
|
||
### 示例
|
||
|
||
你的文档托管在 `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
|
||
import * as jose from 'jose';
|
||
import { Request, Response } from 'express';
|
||
|
||
const TWO_WEEKS_IN_MS = 1000 * 60 * 60 * 24 * 7 * 2;
|
||
|
||
const signingKey = await jose.importPKCS8(process.env.MINTLIFY_PRIVATE_KEY, 'EdDSA');
|
||
|
||
export async function handleRequest(req: Request, res: Response) {
|
||
const user = {
|
||
expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000), // 2 week session expiration
|
||
groups: res.locals.user.groups,
|
||
content: {
|
||
firstName: res.locals.user.firstName,
|
||
lastName: res.locals.user.lastName,
|
||
},
|
||
};
|
||
|
||
const jwt = await new jose.SignJWT(user)
|
||
.setProtectedHeader({ alg: 'EdDSA' })
|
||
.setExpirationTime('10 s') // 10 second JWT expiration
|
||
.sign(signingKey);
|
||
|
||
return res.redirect(`https://docs.foo.com/login/jwt-callback#${jwt}`);
|
||
}
|
||
```
|
||
|
||
```python Python
|
||
import jwt # pyjwt
|
||
import os
|
||
|
||
from datetime import datetime, timedelta
|
||
from fastapi.responses import RedirectResponse
|
||
|
||
private_key = os.getenv(MINTLIFY_JWT_PEM_SECRET_NAME, '')
|
||
|
||
@router.get('/auth')
|
||
async def return_mintlify_auth_status(current_user):
|
||
jwt_token = jwt.encode(
|
||
payload={
|
||
'exp': int((datetime.now() + timedelta(seconds=10)).timestamp()), # 10 second JWT expiration
|
||
'expiresAt': int((datetime.now() + timedelta(weeks=2)).timestamp()), # 1 week session expiration
|
||
'groups': ['admin'] if current_user.is_admin else [],
|
||
'content': {
|
||
'firstName': current_user.first_name,
|
||
'lastName': current_user.last_name,
|
||
},
|
||
},
|
||
key=private_key,
|
||
algorithm='EdDSA'
|
||
)
|
||
|
||
return RedirectResponse(url=f'https://docs.foo.com/login/jwt-callback#{jwt_token}', status_code=302)
|
||
```
|
||
</CodeGroup>
|
||
|
||
### 重定向未认证用户
|
||
|
||
当未认证用户尝试访问受保护页面时,其预期目的地会在重定向到你的登录 URL 时被保留:
|
||
|
||
1. 用户尝试访问受保护页面:`https://docs.foo.com/quickstart`。
|
||
2. 携带重定向 query 参数重定向到你的登录 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
|
||
---
|
||
title: "公开页面"
|
||
public: true
|
||
---
|
||
```
|
||
|
||
<div id="groups-of-pages">
|
||
### 页面分组
|
||
</div>
|
||
|
||
要将某个分组中的所有页面设为公开,请在 `docs.json` 的 `navigation` 对象中,该分组名称下添加 `"public": true`。
|
||
|
||
```json Public group example
|
||
{
|
||
"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 通过在认证过程中传递的用户数据进行管理。
|
||
|
||
```json Example user info highlight={2}
|
||
{
|
||
"groups": ["admin", "beta-users"],
|
||
"content": {
|
||
"firstName": "Jane",
|
||
"lastName": "Doe"
|
||
}
|
||
}
|
||
```
|
||
|
||
使用 frontmatter 中的 `groups` 属性来指定哪些 groups 可以访问特定页面。
|
||
|
||
```mdx Example page restricted to the admin group highlight={3}
|
||
---
|
||
title: "管理员控制台"
|
||
groups: ["admin"]
|
||
---
|
||
```
|
||
|
||
用户必须至少属于所列的一个 groups 才能访问该页面。如果用户在不具备所需分组的情况下尝试访问页面,将会收到 404 错误。
|
||
|
||
<div id="interaction-with-authentication-modes">
|
||
### 与认证模式的交互
|
||
</div>
|
||
|
||
groups 的行为会因认证模式不同而有所差异。
|
||
|
||
**完整认证(配合 groups):**
|
||
|
||
* 所有页面都需要认证。
|
||
* 没有 `groups` 属性的页面对所有已认证用户可访问。
|
||
* 带有 `groups` 属性的页面仅对属于相应 groups 的已认证用户可访问。
|
||
|
||
**部分认证(配合 groups):**
|
||
|
||
* 页面默认需要认证,除非你将其设为公开。
|
||
* 设置了 `public: true` 且没有 `groups` 的页面对所有人可访问。
|
||
* 带有 `groups` 的页面(无论是否设置 `public: true`)仅对属于相应 groups 的已认证用户可访问。
|
||
|
||
```mdx Anyone can view this page
|
||
---
|
||
title: "公开指南"
|
||
public: true
|
||
---
|
||
```
|
||
|
||
````mdx Only authenticated users can view this page
|
||
---
|
||
title: "API 参考"
|
||
---
|
||
|
||
```mdx 只有 pro 或 enterprise 组中的已认证用户可以查看此页面
|
||
---
|
||
title: "高级配置"
|
||
groups: ["pro", "enterprise"]
|
||
---
|
||
````
|