跳转到主要内容
当用户登录后,个性化会为其量身定制你的文档。例如,你可以预填其 API 密钥,展示与其套餐或角色相关的内容,或隐藏其无需访问的部分。

个性化功能

使用以下个性化能力来自定义内容。

API 密钥预填

通过在用户数据中返回与字段名称相同的键,自动为 API交互测试台 的字段填入用户特定的值。要实现自动预填,用户数据中的字段名必须与 API交互测试台 中的字段名称完全一致。

动态 MDX 内容

使用 user 变量,根据用户信息(如姓名、套餐或组织)展示动态内容。
欢迎回来,{user.firstName}!你的 {user.org?.plan} 方案包含……
查看下方用户数据格式部分,了解详细示例和实现指南。

页面可见性

在页面的 frontmatter 中添加 groups 字段,以限制哪些页面对你的用户可见。默认情况下,每个页面对所有用户可见。 用户只会看到其所属 groups 中的页面。
---
title: "管理你的用户"
description: "在你的组织中添加和移除用户"
groups: ["admin"]
---

用户数据格式

在实现个性化时,系统会以特定格式返回用户数据,以支持内容定制。根据握手方式不同,这些数据可以作为原始 JSON 对象发送,或封装在已签名的 JWT 中。两种方式的数据结构一致。
type User = {
  expiresAt?: number;
  groups?: string[];
  content?: Record<string, any>;
  apiPlaygroundInputs?: {
    header?: Record<string, any>;
    query?: Record<string, any>;
    cookie?: Record<string, any>;
    server?: Record<string, string>;
  };
};
expiresAt
number
会话过期时间,单位为自 Unix 纪元以来的秒数。如果用户在此时间之后加载页面,其存储的数据将被自动删除,并且必须重新认证。
对于 JWT 握手:这与 JWT 的 exp 声明不同,后者决定 JWT 何时被视为无效。出于安全考虑,请将 JWT 的 exp 声明设置为较短时长(10 秒或更少)。使用 expiresAt 来设置实际的会话时长(从数小时到数周)。
groups
string[]
用户所属的分组列表。其 frontmatter 中带有匹配 groups 的页面对该用户可见。示例:具有 groups: ["admin", "engineering"] 的用户可以访问带有 adminengineering 分组标签的页面。
content
object
可通过 user 变量在你的 MDX 内容中访问的自定义数据。用于在整个文档中实现动态个性化。基础示例
{ "firstName": "Ronan", "company": "Acme Corp", "plan": "Enterprise" }
MDX 中的用法
Welcome back, {user.firstName}! Your {user.plan} plan includes...
使用示例 user 数据时,将渲染为:Welcome back, Ronan! Your Enterprise plan includes…高级条件渲染
Authentication is an enterprise feature. {
  user.org === undefined
    ? <>To access this feature, first create an account at the <a href="https://dashboard.mintlify.com/login">Mintlify dashboard</a>.</>
    : user.org.plan !== 'enterprise'
      ? <>You are currently on the ${user.org.plan ?? 'free'} plan. See <a href="https://mintlify.com/pricing">our pricing page</a> for information about upgrading.</>
      : <>To request this feature for your enterprise org, contact your admin.</>
}
user 中的信息仅对已登录用户可用。对于未登录用户,user 的值为 {}。为防止页面在未登录情况下崩溃,请始终在 user 字段上使用可选链。例如,{user.org?.plan}
apiPlaygroundInputs
object
用于预填 API 交互测试台字段的用户特定值。在测试 API 时,通过自动填充数据为用户节省时间。示例
{
  "header": { "X-API-Key": "user_api_key_123" },
  "server": { "subdomain": "foo" },
  "query": { "org_id": "12345" }
}
如果某个用户在特定子域发起请求,你可以将 { server: { subdomain: 'foo' } } 作为 apiPlaygroundInputs 字段发送。该值会在任何包含 subdomain 字段的 API 页面上被预填。
仅当 headerquerycookie 字段属于你的 OpenAPI security scheme 时才会预填。如果某个字段位于 AuthorizationServer 部分,它将被预填。创建一个名为 Authorization 的标准 Header 参数并不会启用此功能。

示例用户数据

{
  "expiresAt": 1735689600,
  "groups": ["admin", "beta-users"],
  "content": {
    "firstName": "Jane",
    "lastName": "Smith",
    "company": "TechCorp",
    "plan": "Enterprise",
    "region": "us-west"
  },
  "apiPlaygroundInputs": {
    "header": {
      "Authorization": "Bearer abc123",
      "X-Org-ID": "techcorp"
    },
    "server": {
      "environment": "production",
      "region": "us-west"
    }
  }
}

配置个性化

选择要配置的握手机制。
  • JWT
  • OAuth 2.0
  • 共享会话

先决条件

  • 一个能够生成并签署 JWT 的登录系统
  • 一个能够创建重定向 URL 的后端服务

实施

1

生成私钥。

  1. 在你的控制台中,前往 Authentication
  2. 选择 Personalization(个性化)
  3. 选择 JWT
  4. 输入你现有登录流程的 URL,并选择 Save changes(保存更改)
  5. 选择 Generate new key(生成新密钥)
  6. 将密钥安全存放在后端可访问的位置。
2

将 Mintlify 个性化集成到你的登录流程中。

在用户登录后,修改你现有的登录流程以包含以下步骤:
  • 使用 User 格式创建一个包含已登录用户信息的 JWT。有关更多信息,请参见上方的 User data format 部分。
  • 使用 ES256 算法与该私钥对 JWT 进行签名。
  • 创建一个返回到文档站点的重定向 URL,并将 JWT 作为哈希附加其后。

示例

你的文档托管在 docs.foo.com。你希望文档与控制台分离(或你没有控制台)并启用个性化。先生成一个 JWT 密钥。然后在 https://foo.com/docs-login 创建一个登录端点,以启动到文档的登录流程。在验证用户凭据之后:
  • 以 Mintlify 的格式生成包含用户数据的 JWT。
  • 对 JWT 进行签名并重定向到 https://docs.foo.com#{SIGNED_JWT}
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, 'ES256');

export async function handleRequest(req: Request, res: Response) {
  const user = {
    expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000),
    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: 'ES256' })
    .setExpirationTime('10 s')
    .sign(signingKey);

  return res.redirect(`https://docs.foo.com#${jwt}`);
}

保留页面锚点

若要在登录后将用户重定向到特定小节,请使用以下 URL 格式:https://docs.foo.com/page#jwt={SIGNED_JWT}&anchor={ANCHOR}示例
  • 原始 URL:https://docs.foo.com/quickstart#step-one
  • 重定向后的 URL:https://docs.foo.com/quickstart#jwt={SIGNED_JWT}&anchor=step-one