# How Cookies Are Managed by the Nitro Server-Side Proxy in wechat-article-exporter

> Learn how the Nitro server-side proxy in wechat-article-exporter manages authentication cookies by forwarding them to the WeChat MP API and persisting new Set-Cookie values.

- Repository: [公众号文章工具箱/wechat-article-exporter](https://github.com/wechat-article/wechat-article-exporter)
- Tags: internals
- Published: 2026-05-26

---

**The Nitro server-side proxy in wechat-article-exporter manages authentication cookies by extracting them from incoming requests or a persistent CookieStore, forwarding them to the WeChat MP API, and persisting new Set-Cookie values to a KV-backed LRU cache during the login flow.**

The `wechat-article/wechat-article-exporter` repository implements a Nitro-based server-side proxy to interact with the WeChat MP (Official Accounts Platform) API. Managing authentication state securely and efficiently requires careful handling of cookies across the boundary between client requests and upstream MP endpoints. This article examines how the Nitro server-side proxy handles cookie selection, forwarding, and persistent storage according to the actual implementation in the source code.

## Cookie Selection from Incoming Requests

In [`server/utils/proxy-request.ts`](https://github.com/wechat-article/wechat-article-exporter/blob/main/server/utils/proxy-request.ts), the proxy builds a `Headers` object for every outbound MP request. The cookie selection logic at lines 24-28 prioritizes an explicit cookie passed via `options.cookie`. If none is provided, the proxy calls `getCookieFromStore(event)` to retrieve stored credentials.

The `getCookieFromStore` function (defined in [`server/utils/CookieStore.ts`](https://github.com/wechat-article/wechat-article-exporter/blob/main/server/utils/CookieStore.ts) at lines 27-50) implements a two-step lookup:

- First, it checks for an `X-Auth-Key` header in the incoming request.
- If absent, it reads the `auth-key` cookie from the request headers.
- Using this key, it retrieves the stored cookie string from the `CookieStore`, which maintains an in-memory LRU cache backed by KV storage.

This abstraction allows the proxy to handle authenticated requests without requiring the client to transmit sensitive session cookies directly.

## Forwarding Authentication to the WeChat MP API

Once the appropriate cookie string is selected, the proxy attaches it to a `Request` object (line 45 of [`proxy-request.ts`](https://github.com/wechat-article/wechat-article-exporter/blob/main/proxy-request.ts)) and dispatches it to the WeChat MP endpoint using `fetch`. When debugging is enabled, the request details are logged at lines 48-52, including the target endpoint and method.

The proxy acts as a transparent intermediary, ensuring the WeChat servers receive the necessary `Cookie` header while the underlying `CookieStore` handles the complexity of key management and retrieval from the KV layer.

## Handling Set-Cookie Responses by Action Type

After receiving the MP response, the proxy extracts the `Set-Cookie` header array via `mpResponse.headers.getSetCookie()`. The handling logic branches based on the `options.action` parameter:

- **`start_login`** – Extracts only the `uuid=` cookie from the response and forwards it to the client (line 66).

- **`login`** – Parses the JSON response body to obtain the `redirect_url`, extracts the `token` query parameter, and writes the full set of cookies to persistent storage via `cookieStore.setCookie(authKey, token, mpResponse.headers.getSetCookie())` (lines 88-90). It then generates an `auth-key` cookie for the client browser (lines 95-99), enabling subsequent requests to reference the stored session.

- **`switch_account`** – Appends a `switch_account=1` cookie to the response without complex parsing.

Finally, the proxy creates a new `Headers` object based on the original response, removes any upstream `set-cookie` entries to prevent leakage, and injects the prepared cookies using `responseHeaders.append('set-cookie', ...)` before returning the final `Response` to the client.

## Persistent Storage Architecture

The `CookieStore` class in [`server/utils/CookieStore.ts`](https://github.com/wechat-article/wechat-article-exporter/blob/main/server/utils/CookieStore.ts) manages the lifecycle of authentication data beyond individual requests. It maintains a `Map<authKey, AccountCookie>` with an LRU (Least Recently Used) eviction policy.

When `setCookie` is called during a login action, the store:

1. Creates an `AccountCookie` object from the raw `set-cookie` strings.
2. Stores it in the in-memory LRU map.
3. Persists the JSON representation to the KV layer via `setMpCookie` (lines 66-67).

Retrieval via `getCookie` (lines 47-53) checks the memory cache first, then falls back to KV storage using `getMpCookie` if the entry is not present. The method returns a formatted string suitable for the `Cookie` request header by calling `accountCookie.toString()`.

To prevent unbounded memory growth, the `evictIfNeeded` method (lines 81-90) enforces the configured `maxSize` limit, removing the oldest entries from the LRU map when the threshold is exceeded.

## Practical Implementation Examples

The following examples demonstrate how to interact with the cookie management system from server-side code:

```typescript
// Invoking the proxy without explicit cookie (auto-retrieval from CookieStore)
import { proxyMpRequest } from '~/server/utils/proxy-request';

export async function fetchArticleList(event: H3Event) {
  return proxyMpRequest({
    event,
    endpoint: 'https://mp.weixin.qq.com/cgi-bin/appmsg',
    method: 'GET',
    action: 'fetch_articles',
    // Cookie is automatically fetched from the store based on auth-key
  });
}

```

```typescript
// Manually retrieving a stored cookie for external service calls
import { getCookieFromStore } from '~/server/utils/CookieStore';

export async function someServerSideJob(event: H3Event) {
  const cookieHeader = await getCookieFromStore(event);
  // Use cookieHeader to call external services on behalf of the logged-in user
}

```

```typescript
// Login endpoint that triggers cookie persistence
import { proxyMpRequest } from '~/server/utils/proxy-request';

export default defineEventHandler(async (event) => {
  // Frontend sends credentials; proxy handles the full cookie lifecycle
  return await proxyMpRequest({
    event,
    endpoint: 'https://mp.weixin.qq.com/cgi-bin/login',
    method: 'POST',
    action: 'login',
    body: { username, pwd },
  });
});

```

## Summary

- The Nitro proxy in [`server/utils/proxy-request.ts`](https://github.com/wechat-article/wechat-article-exporter/blob/main/server/utils/proxy-request.ts) transparently forwards cookies to the WeChat MP API while managing authentication flow complexity through a centralized utility.
- Cookie selection prioritizes explicit `options.cookie` values, then falls back to the KV-backed `CookieStore` via `getCookieFromStore`, supporting both header-based and cookie-based authentication keys.
- Three distinct actions (`start_login`, `login`, `switch_account`) handle different phases of the authentication lifecycle, with the `login` action specifically persisting the full cookie jar to long-term storage.
- The `CookieStore` provides LRU-cached, KV-persisted storage for `AccountCookie` objects, ensuring bounded memory usage through automatic eviction while maintaining persistent sessions across server restarts.

## Frequently Asked Questions

### How does the proxy decide which cookie to use for a request?

The proxy first checks for an explicitly provided cookie in `options.cookie`. If none exists, it calls `getCookieFromStore(event)`, which looks for an `X-Auth-Key` header or an `auth-key` cookie in the request, then retrieves the associated session from the in-memory cache or KV storage.

### What happens to cookies during the login action?

During the `login` action, the proxy parses the WeChat MP response to extract a token from the `redirect_url`, then calls `cookieStore.setCookie()` to persist all `Set-Cookie` headers to the KV-backed store. It also generates a new `auth-key` cookie for the client, which serves as a reference key for future requests.

### How are cookies persisted between server restarts?

The `CookieStore` class writes cookie data to a KV (Key-Value) storage layer via `setMpCookie` whenever cookies are updated. When retrieving cookies, it first checks the in-memory LRU cache; if the entry is missing, it falls back to `getMpCookie` to load the data from persistent storage, ensuring sessions survive server restarts.

### What prevents the cookie store from consuming too much memory?

The `CookieStore` implements an LRU (Least Recently Used) eviction policy through the `evictIfNeeded` method (lines 81-90 of [`CookieStore.ts`](https://github.com/wechat-article/wechat-article-exporter/blob/main/CookieStore.ts)). When the number of stored entries exceeds the configured `maxSize`, the oldest entries are automatically removed from the in-memory map, while the data remains safely stored in the KV layer for future retrieval.