How the Nitro Server-Side Proxy Handles WeChat API Requests
The Nitro server-side proxy acts as a secure intermediary by forwarding client requests to WeChat MP endpoints with forged headers, managing authentication cookies via an LRU-backed store, and sanitizing responses to prevent CORS issues.
The wechat-article/wechat-article-exporter repository leverages Nuxt 3's Nitro engine to circumvent browser restrictions when interfacing with the WeChat public platform (MP). All WeChat API calls flow through a dedicated server-side proxy that normalizes headers, maintains authentication state, and cleans response cookies before they reach the client.
Request Flow Architecture
The proxy implementation centers on the proxyMpRequest() function defined in [server/utils/proxy-request.ts](https://github.com/wechat-article/wechat-article-exporter/blob/master/server/utils/proxy-request.ts). When the front-end invokes a Nitro API route (e.g., server/api/web/mp/...), execution passes through this utility, which orchestrates header preparation, cookie retrieval, and response sanitization.
Header Preparation and Security
Inside proxyMpRequest, the function constructs a Headers object mandatory for WeChat acceptance:
- Referer and Origin are hard-coded to
https://mp.weixin.qq.com/to satisfy WeChat's domain validation - User-Agent is injected from the constant defined in [
config/public-proxy.ts](https://github.com/wechat-article/wechat-article-exporter/blob/master/config/public-proxy.ts) - Accept-Encoding is set to
identityto prevent compression, ensuring the response body can be cloned and processed reliably
These headers are applied to a native Request object before forwarding.
Cookie Handling and Authentication
The proxy retrieves stored credentials through getCookieFromStore in [server/utils/CookieStore.ts](https://github.com/wechat-article/wechat-article-exporter/blob/master/server/utils/CookieStore.ts). The logic branches based on the incoming request:
- If the caller explicitly provides a
cookievalue in the options object, that string is used directly - Otherwise, the utility inspects the
X-Auth-Keyheader orauth-keycookie, then fetches the associatedAccountCookiefrom either an in-memory LRU cache or the persistent KV store
The resulting cookie string is attached to the outgoing request, allowing the proxy to impersonate a logged-in browser session.
Request Construction and Forwarding
For POST requests, the proxy URL-encodes the body as application/x-www-form-urlencoded before constructing the final Request instance. The endpoint URL may be extended with query parameters supplied via options.query. When the environment variable NUXT_DEBUG_MP_REQUEST is set, the fully formed request is logged for debugging.
Because the proxy executes on the server, it uses fetch() to communicate with WeChat endpoints without triggering browser CORS preflight checks or cookie restrictions.
Response Processing and Action Handlers
After receiving the WeChat response, the proxy executes action-specific logic based on options.action:
start_login– Extracts the temporaryuuidcookie set by the WeChat login pagelogin– Parses the JSON body to extractredirect_url, retrieves thetokenparameter, and persists the complete cookie set viacookieStore.setCookie. It returns twoSet-Cookieheaders to the client: a newauth-key(4-day expiry) and an expireduuidto clear the temporary sessionswitch_account– Appends aswitch_account=1cookie to signal account context changes
The proxy strips all original Set-Cookie headers from WeChat to prevent client-side exposure, injecting only the sanitized proxy-managed cookies.
Cookie Store Mechanics
The CookieStore utility maintains state through an LRU-style in-memory Map<string, AccountCookie> backed by a KV storage layer (server/kv/cookie.ts).
Each AccountCookie instance parses raw Set-Cookie strings into structured CookieEntity objects and can serialize them back into HTTP-ready header strings via the toString() method. When setCookie is invoked, the update is written to both the in-memory cache for immediate subsequent lookups and the KV store for persistence across server restarts.
Practical Implementation Examples
The following patterns demonstrate how to invoke the proxy within Nitro API routes:
// server/api/articles/list.get.ts
import { proxyMpRequest } from '@/server/utils/proxy-request';
export default defineEventHandler(async (event) => {
const authKey = getCookie(event, 'auth-key');
return proxyMpRequest({
endpoint: 'https://mp.weixin.qq.com/cgi-bin/home',
method: 'GET',
action: 'fetch_articles',
query: { t: 'home/index', lang: 'zh_CN' },
cookie: undefined, // pulled automatically from store via authKey
event,
parseJson: true,
});
});
// server/api/auth/login.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
return proxyMpRequest({
endpoint: 'https://mp.weixin.qq.com/cgi-bin/login',
method: 'POST',
action: 'login',
body: { username: body.user, pwd: body.pass },
event,
parseJson: false, // returns redirect URL in body
});
});
Summary
- CORS Bypass: The Nitro server-side proxy executes requests outside browser constraints, eliminating preflight issues when contacting
mp.weixin.qq.com - Header Forgery: Fixed
Referer,Origin, andUser-Agentheaders convince WeChat servers the request originates from an official domain - Authentication Management: The
CookieStoreutility persists sessions via an LRU cache backed by KV storage, keyed byauth-keytokens - Login Flow Support: Special actions (
start_login,login) handle UUID extraction, token parsing fromredirect_url, and cookie rotation - Security Sanitization: Original WeChat
Set-Cookieheaders are stripped and replaced with proxy-controlled equivalents to prevent credential leakage
Frequently Asked Questions
Why does the proxy need to spoof Referer and Origin headers?
WeChat's MP platform validates the source of incoming requests to prevent CSRF and unauthorized scraping. By setting both Referer and Origin to https://mp.weixin.qq.com/, the Nitro server-side proxy satisfies these security checks, allowing the API to accept the request as if it came from an authenticated browser session on the official domain.
How does the CookieStore handle session persistence across server restarts?
The CookieStore maintains a hot in-memory Map for low-latency lookups during active requests, but delegates long-term storage to a KV backend defined in server/kv/cookie.ts. When setCookie is called, the utility writes to both layers simultaneously, ensuring that even if the Nitro process restarts, the auth-key can still retrieve the associated AccountCookie from persistent storage.
What is the difference between the uuid and auth-key cookies?
The uuid cookie is a temporary identifier generated during the start_login phase that tracks the initial login session on WeChat's servers. Upon successful authentication (login action), the proxy exchanges this temporary cookie for a permanent session identified by auth-key, which is stored in the CookieStore and valid for four days. The proxy then instructs the client to expire the uuid cookie since it is no longer needed.
Why must Accept-Encoding be set to identity instead of allowing compression?
The proxy disables compression by forcing Accept-Encoding: identity because the Nitro server needs to potentially clone and inspect the response body before forwarding it to the client. Compressed responses (gzip/deflate) can only be read once and cannot be trivially cloned for logging or JSON parsing without consuming the stream, which would break subsequent transmission to the client.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →