# 身份验证

如果你的 GitBook 文档需要身份验证（例如通过 OIDC、Auth0 或自定义后端进行访客身份验证），则除非提供用户的身份验证令牌，否则嵌入内容无法访问你的文档内容。

有两种方法：

1. **直接传递令牌** （推荐）- 使用访客令牌初始化嵌入
2. **使用基于 Cookie 的检测** - 在加载前检查 Cookie 中是否存在令牌

## 方法 1：直接传递令牌（推荐）

初始化嵌入时，直接传递访客令牌：

{% tabs %}
{% tab title="独立脚本" %}

```html
<script src="https://docs.company.com/~gitbook/embed/script.js?jwt_token=your-jwt-token"></script>
<script>
  window.GitBook(
    "init",
    { siteURL: "https://docs.company.com" },
    { visitor: { token: "your-jwt-token" } }
  );
  window.GitBook("show");
</script>
```

{% endtab %}

{% tab title="NPM 包" %}

```javascript
import { createGitBook } from "@gitbook/embed";

const gitbook = createGitBook({
  siteURL: "https://docs.company.com",
});

const iframe = document.createElement("iframe");
iframe.src = gitbook.getFrameURL({
  visitor: {
    token: "your-jwt-token",
    unsignedClaims: { userId: "123", plan: "premium" },
  },
});
```

{% endtab %}

{% tab title="React 组件" %}

```jsx
<GitBookProvider siteURL="https://docs.company.com">
  <GitBookFrame
    visitor={{
      token: "your-jwt-token",
      unsignedClaims: { userId: "123" },
    }}
  />
</GitBookProvider>
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Embed 配置 API 没有变化。将已签名的访客令牌传递为 `visitor.token`.

对于已认证站点，GitBook 会将此令牌转发给站点，形式为 `jwt_token` ，位于 iframe/script URL 中。如果你从已认证站点加载独立脚本，则必须在 `jwt_token` 后，在 `<script src>` URL 中包含它。
{% endhint %}

## 方法 2：基于 Cookie 的检测

如果你的文档站点将访客令牌存储在 Cookie 中（如 `gitbook-visitor-token`），则你可以在加载嵌入之前检查它。

当用户登录到你的已认证文档时，GitBook 会将访客令牌存储到其浏览器 Cookie 中，键名为 `gitbook-visitor-token`。嵌入需要此令牌才能从你的文档中获取内容。

**流程如下：**

1. 用户登录到你的文档站点
2. GitBook 将访客令牌存储到浏览器 Cookie 中
3. 你的应用检查令牌
4. 如果令牌存在，则加载嵌入并传递令牌
5. 如果令牌不存在，则提示用户登录

{% tabs %}
{% tab title="独立脚本" %}

#### 复制粘贴片段

使用此代码片段，在用户登录后才加载嵌入：

```html
<script>
  (function () {
    // 检查 Cookie 中的访客令牌
    function getCookie(name) {
      var value = "; " + document.cookie;
      var parts = value.split("; " + name + "=");
      if (parts.length === 2) return parts.pop().split(";").shift();
    }

    var token = getCookie("gitbook-visitor-token");

    if (!token) {
      console.warn("[Docs Embed] 请先登录你的文档。");
      return;
    }

    // 令牌存在，加载嵌入
    var script = document.createElement("script");
    script.src =
      "https://docs.example.com/~gitbook/embed/script.js?jwt_token=" +
      encodeURIComponent(token);
    script.async = true;
    script.onload = function () {
      window.GitBook(
        "init",
        { siteURL: "https://docs.example.com" },
        { visitor: { token: token } }
      );
      window.GitBook("show");
    };
    document.head.appendChild(script);
  })();
</script>
```

{% hint style="warning" %}
替换 `docs.example.com` 替换为你实际的文档站点 URL。
{% endhint %}

#### 替代方案：提示用户登录

如果令牌缺失，你可以提示用户登录：

```html
<script>
  (function () {
    function getCookie(name) {
      var value = "; " + document.cookie;
      var parts = value.split("; " + name + "=");
      if (parts.length === 2) return parts.pop().split(";").shift();
    }

    var token = getCookie("gitbook-visitor-token");

    if (!token) {
      // 重定向到文档或显示一条消息
      alert("请先登录你的文档以访问帮助内容。");
      window.location.href = "https://docs.example.com";
      return;
    }

    // 使用令牌加载嵌入
    var script = document.createElement("script");
    script.src =
      "https://docs.example.com/~gitbook/embed/script.js?jwt_token=" +
      encodeURIComponent(token);
    script.async = true;
    script.onload = function () {
      window.GitBook(
        "init",
        { siteURL: "https://docs.example.com" },
        { visitor: { token: token } }
      );
      window.GitBook("show");
    };
    document.head.appendChild(script);
  })();
</script>
```

{% endtab %}

{% tab title="NPM 包" %}
使用 NPM 包时，在初始化前先检查令牌：

```javascript
import { createGitBook } from "@gitbook/embed";

function initializeEmbed() {
  // 检查 Cookie 中的令牌
  const getCookie = (name) => {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(";").shift();
  };

  const token = getCookie("gitbook-visitor-token");

  if (!token) {
    console.warn("[Docs Embed] 用户必须先登录。");
    return null;
  }

  const gitbook = createGitBook({
    siteURL: "https://docs.example.com",
  });

  const iframe = document.createElement("iframe");
  iframe.src = gitbook.getFrameURL({
    visitor: { token: token },
  });
  const frame = gitbook.createFrame(iframe);

  document.getElementById("embed-container").appendChild(iframe);
  return frame;
}

initializeEmbed();
```

{% endtab %}

{% tab title="React 组件" %}
对于 React 应用，可根据令牌是否存在有条件地渲染嵌入：

```jsx
import { useEffect, useState } from "react";
import { GitBookProvider, GitBookFrame } from "@gitbook/embed/react";

function App() {
  const [token, setToken] = useState(null);

  useEffect(() => {
    // 检查 Cookie 中的令牌
    const getCookie = (name) => {
      const value = `; ${document.cookie}`;
      const parts = value.split(`; ${name}=`);
      if (parts.length === 2) return parts.pop().split(";").shift();
    };

    const visitorToken = getCookie("gitbook-visitor-token");
    setToken(visitorToken);
  }, []);

  if (!token) {
    return (
      <div>
        <p>请先登录以访问帮助内容。</p>
        <a href="https://docs.example.com">登录</a>
      </div>
    );
  }

  return (
    <GitBookProvider siteURL="https://docs.example.com">
      <YourAppContent />
      <GitBookFrame visitor={{ token: token }} />
    </GitBookProvider>
  );
}
```

{% endtab %}
{% endtabs %}

## 常见问题

* **在登录前加载嵌入** – 始终在加载脚本或组件前检查令牌，或者在初始化时直接传递令牌。
* **令牌未在跨域间持久化** – 由于浏览器安全策略，Cookie 不会在不同域之间持久化。你的应用和文档必须位于同一域或子域下，或者直接传递令牌。
* **令牌已过期** – 令牌可能会过期。如果嵌入返回身份验证错误，请提示用户重新登录。
* **使用了错误的 Cookie 名称** – 令牌存储为 `gitbook-visitor-token`，而不是 `gitbook-token` 或其他变体。
* **未将令牌传递给 init/getFrameURL** – 使用基于 Cookie 的方法时，确保将令牌传递给 `GitBook('init', ..., { visitor: { token } })` 或者 `getFrameURL({ visitor: { token } })`.

## 调试

要验证令牌是否存在，请打开浏览器控制台并运行：

```javascript
document.cookie.split(";").find((c) => c.includes("gitbook-visitor-token"));
```

如果这返回 `undefined`，说明用户尚未登录你的文档。

## 后续步骤

* [自定义嵌入](https://gitbook-open-v2-preview.gitbook.workers.dev/url/gitbook.com/docs/documentation/zh/publishing-documentation/embedding/configuration/customizing-docs-embed) – 添加欢迎消息和操作
* [创建自定义工具](https://gitbook-open-v2-preview.gitbook.workers.dev/url/gitbook.com/docs/documentation/zh/publishing-documentation/embedding/configuration/creating-custom-tools) – 与你的产品 API 集成
* [Docs Embed 文档](https://gitbook-open-v2-preview.gitbook.workers.dev/url/gitbook.com/docs/documentation/zh/publishing-documentation/embedding) – 完整嵌入指南
