# Cookie

{% hint style="info" %}
前往我们的指南，找到一个 [完整演示](/docs/guides/docs-personalization-and-authentication/setting-up-adaptive-content.md) 关于使用 cookie 设置自适应内容。
{% endhint %}

{% hint style="warning" %}
将自适应内容与功能标志一起使用需要向你的应用程序添加代码。

此方法仅在你的网站托管于以下域名下时有效： [自定义域名](/docs/documentation/zh/docs-site/custom-domain.md).
{% endhint %}

你可以通过访客浏览器中的 cookie 将访客数据传递到你的文档中。下面是不同方法的概览。

<table data-full-width="false"><thead><tr><th width="335.125">方法</th><th width="266.6015625">使用场景</th><th width="206.58984375">设置难度</th><th width="202">安全性</th><th>格式</th></tr></thead><tbody><tr><td>签名 cookie <code>gitbook-visitor-token</code></td><td>API 测试凭据、客户识别</td><td>需要签名和自定义域名</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span> 属性只能由后端定义</td><td>JWT</td></tr><tr><td>公共 cookie <code>gitbook-visitor-public</code></td><td>功能标志、角色</td><td>易于设置</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span> 访客可以覆盖这些属性</td><td>JSON</td></tr></tbody></table>

### 公共 cookie

要通过公共 cookie 将数据传递到 GitBook，你需要通过设置一个公共 `gitbook-visitor-public` cookie，从你的应用程序发送数据。

以下是一个简单的 JavaScript 示例：

```javascript
import Cookies from 'js-cookie';

const cookieData = {
  isLoggedIn: true,
  isBetaUser: false,
};

Cookies.set('gitbook-visitor-public', JSON.stringify(cookieData), {
  secure: true,
  domain: '*.acme.org',
})
```

{% hint style="warning" %}
通过公共 cookie 传递的数据必须通过一个 [未签名的](https://gitbook.com/docs/publishing-documentation/adaptive-content/enabling-adaptive-content#setting-unsigned-claims) 对象在你的访客架构中定义。
{% endhint %}

### 签名 cookie

要更安全地将数据传递到 GitBook，你需要将数据作为 [JSON Web Token](https://jwt.io/introduction) 从你的应用程序中以名为 `gitbook-visitor-token` 的 cookie 形式发送，并绑定到你的域名。

要进行此设置，你需要调整应用程序的登录流程，以包含以下步骤：

{% stepper %}
{% step %}
**当用户登录到你的应用程序时生成 JWT**

每当用户登录到你的产品时，生成一个包含你已认证用户信息中选定属性的 JWT。
{% endstep %}

{% step %}
**使用站点的访客签名密钥对 JWT 进行签名**

然后，确保使用站点的 **访客签名密钥**对 JWT 进行签名，你可以在启用自适应内容后于站点的受众设置中找到该密钥。
{% endstep %}

{% step %}
**将 JWT 存储在通配符会话 cookie 中**

最后，你需要将包含用户信息的已签名 JWT 存储到一个通配符会话 cookie 中 **位于你的产品域名下**.

例如，如果你的应用程序托管在 `app.acme.org` 域名之后，那么 cookie 需要创建在 `.acme.org` 通配符域名下。
{% endstep %}
{% endstepper %}

以下是一个简单的 TypeScript 示例：

```typescript
import * as jose from 'jose';

import { Request, Response } from 'express';

import { getUserInfo } from '../services/user-info-service';
import { getFeatureFlags } from '../services/feature-flags-service';

const GITBOOK_VISITOR_SIGNING_KEY = process.env.GITBOOK_VISITOR_SIGNING_KEY;
const GITBOOK_VISITOR_COOKIE_NAME = 'gitbook-visitor-token';


export async function handleAppLoginRequest(req: Request, res: Response) {
   // 处理登录请求的业务逻辑
   // 例如，检查凭据并验证用户身份
   //
   // 例如：
   // const loggedInUser = await authenticateUser(req.body.username, req.body.password);

   // 在认证用户后，从你的数据库或用户服务中检索你希望
   // 传递给 GitBook 的用户信息。
   const userInfo = await getUserInfo(loggedInUser.id);
      
   // 使用用户信息构建 JWT 载荷
   const gitbookVisitorClaims = {
       firstName: userInfo.firstName,
       lastName: userInfo.lastName,
       isBetaUser: userInfo.isBetaUser
       products: userInfo.products.map((product) => product.name),
       featureFlags: await getFeatureFlags({userId: loggedInUser.id})
   }
   
   // 使用这些声明生成已签名的 JWT
   const gitbookVisitorJWT = await new jose.SignJWT(gitbookVisitorClaims)
     .setProtectedHeader({ alg: 'HS256' })
     .setIssuedAt()
     .setExpirationTime('2h') // 任意 2 小时过期
     .sign(GITBOOK_VISITOR_SIGNING_KEY);
     
  // 在你的登录处理器响应中包含一个 `gitbook-visitor-token` cookie，
  // 其中包含编码后的 JWT
  res.cookie(GITBOOK_VISITOR_COOKIE_NAME, gitbookVisitorJWT, {
     httpOnly: true,
     secure: process.env.NODE_ENV === 'production',
     maxAge: 2 * 60 * 60 * 1000, // 任意 2 小时过期
     domain: '.acme.org' //
  });
  
  // 登录处理器的其余逻辑，包括将用户重定向到你的应用
  res.redirect('/'); // 示例重定向
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.com/docs/documentation/zh/zhan-dian-fang-wen/adaptive-content/enabling-adaptive-content/cookies.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
