For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
预约演示登录免费开始
  • 入门
    • 概览
    • 工作原理
    • 快速开始
    • 项目结构
    • Customer showcase
    • 变更日志
  • 配置
    • 概览
    • 站点级设置
    • 页面级设置
  • 编写内容
    • Markdown 基础
    • Markdown 中的富媒体
    • Fern 编辑器
    • 可复用代码片段
  • AI 功能
    • 概览
    • Fern Writer
    • AI 生成的示例
    • Markdown 访问
      • 概览
      • Agent 指令
      • 智能体指令
      • 分析与集成
    • MCP 服务器
    • API 目录发现
      • 概览
        • 密码保护
        • 单点登录
        • 设置 JWT
        • 设置 OAuth
  • Public API
    • GETJWT from Fern API key
    • GETAlgolia search credentials
    • GETCurrent user information
  • Fern Writer API
    • GETGet Fern Writer Install Link
Checking status...
SOC2Soc 2 Type II
© 2026 Fern • Birch Solutions, Inc., a Postman company

Documentation

SDKsDocsAsk FernCLI Reference

API Definitions

OpenAPIAsyncAPIOpenRPCgRPC

Resources

BlogSupportPricing

Company

Brand KitPrivacy PolicyTerms of Service
LogoLogo
预约演示登录免费开始
在本页
  • 工作原理
  • 配置
本地化Setup

设置 JWT

与您的登录系统集成的自管理身份验证

||以 Markdown 格式查看|
此页面是否有帮助?
在仪表板中编辑
上一个

单点登录

下一个

设置 OAuth

企业功能

此功能仅适用于企业计划。如需开始使用,请联系 support@buildwithfern.com。

使用 JWT,您可以管理整个身份验证流程。这涉及构建和签署一个 fern_token cookie,将您的文档与现有登录系统集成。与 OAuth 类似,JWT 支持:

  • 仅登录 — 通过身份验证来保护文档
  • RBAC — 按用户角色限制内容
  • API 密钥注入 — 在 API Explorer 中预填充 API 密钥

工作原理

  1. 用户在您的文档站点上点击 登录,然后被重定向到您的身份验证页面。
  2. 身份验证后,您的系统使用来自 Fern 的密钥签署一个 JWT,并将其设置为 fern_token cookie。
  3. Fern 读取令牌以确定用户的访问权限和凭据。
架构图

配置

1

获取您的密钥

联系 Fern 获取您的密钥,并向他们发送您的身份验证页面 URL。这是用户点击 登录 后被重定向的地方。

2

构建 fern 声明

JWT 负载必须包含一个 fern 声明。您在令牌的 fern 声明中包含的内容控制启用的功能:仅登录、RBAC 或 API 密钥注入。

1{
2 "fern": {}
3}
3

设置 fern_token cookie

在您的服务中添加逻辑,在用户登录时签署 JWT 并将其设置为 fern_token cookie。

示例:完整的回调端点

这个 Next.js 端点处理来自您的身份验证页面的回调。它读取 state 参数来确定将用户重定向到何处,使用 jose 生成 fern_token JWT,将其设置为 cookie,并将用户重定向回文档。

app/api/fern-token/route.ts
1import { SignJWT } from "jose";
2import { cookies } from "next/headers";
3import { type NextRequest, NextResponse } from "next/server";
4
5export async function GET(req: NextRequest): Promise<NextResponse> {
6 const domain = getDomain(req); // your logic to determine the docs domain
7
8 // use the state param to determine redirect location
9 const returnTo = req.nextUrl.searchParams.get("state");
10 const redirectLocation = returnTo ?? `https://${domain}`;
11
12 // fetch the user's API key, roles, and secret (from your config or database)
13 const apiKey = await getApiKeyForUser();
14 const roles = await getRolesForUser();
15 const secret = await getSecretForDomain(domain);
16
17 if (!secret) {
18 // redirect with an error if credentials are missing
19 const url = new URL(redirectLocation);
20 url.searchParams.set("error", "missing_credentials");
21 return NextResponse.redirect(url);
22 }
23
24 // mint the JWT using the secret key
25 const fernToken = await mintFernToken({ secret, apiKey, roles });
26
27 if (!fernToken) {
28 const url = new URL(redirectLocation);
29 url.searchParams.set("error", "token_creation_failed");
30 return NextResponse.redirect(url);
31 }
32
33 // set the fern_token as a cookie on the docs domain
34 const cookieJar = await cookies();
35 cookieJar.set("fern_token", fernToken, {
36 httpOnly: true,
37 secure: true,
38 sameSite: "lax",
39 domain,
40 });
41
42 // redirect the user back to the docs
43 return NextResponse.redirect(redirectLocation);
44}
45
46const encoder = new TextEncoder();
47
48async function mintFernToken({
49 secret,
50 apiKey,
51 roles,
52}: {
53 secret: string;
54 apiKey?: string;
55 roles?: string[];
56}): Promise<string> {
57 const fern: Record<string, unknown> = {};
58
59 if (roles) {
60 fern.roles = roles;
61 }
62
63 if (apiKey) {
64 fern.playground = {
65 initial_state: {
66 auth: {
67 bearer_token: apiKey,
68 },
69 },
70 };
71 }
72
73 return await new SignJWT({ fern })
74 .setProtectedHeader({ alg: "HS256", typ: "JWT" })
75 .setIssuedAt()
76 .setExpirationTime("1d") // set to any value
77 .setIssuer("https://buildwithfern.com")
78 .sign(encoder.encode(secret)); // sign using the secret provided by Fern
79}
4

启用 RBAC 或 API 密钥注入(可选)

一旦您的 fern_token 工作正常,配置您需要的功能:

  • 基于角色的访问控制 — 在 docs.yml 中定义角色,并按角色限制导航项或页面内容。
  • API 密钥注入 — 配置 playground 负载,包括自定义标头、多个 API 密钥和按环境凭据。