Skip to content

Commit 5469b02

Browse files
authored
fix(route/zhihu): auto-fetch __zse_ck when absent from ZHIHU_COOKIES (#21321)
When ZHIHU_COOKIES is configured without __zse_ck, automatically fetch the value from Zhihu's public static JS (static.zhihu.com/zse-ck/v3.js). __zse_ck is a site-wide token (not user-specific) that Zhihu embeds in a static JS file and rotates periodically. When it expires, routes that scrape HTML pages (e.g. /zhihu/posts/people/:id) return 403, while API-only routes are unaffected. Users can now omit __zse_ck from ZHIHU_COOKIES and it will be fetched and cached automatically, eliminating manual cookie rotation for this token. Existing configs that include __zse_ck are unchanged.
1 parent 829d7f0 commit 5469b02

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

lib/routes/zhihu/utils.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,24 @@ export const getSignedHeader = async (url: string, apiPath: string) => {
7272
const xzse93 = '101_3_3.0';
7373
const f = `${xzse93}+${apiPath}+${dc0}`;
7474
const xzse96 = '2.0_' + g_encrypt(md5(f));
75+
76+
// If __zse_ck is absent from ZHIHU_COOKIES, fetch it automatically from
77+
// Zhihu's public static JS. The value is site-wide (not user-specific)
78+
// and requires no login, but it expires and must be kept up to date.
79+
let cookieStr = config.zhihu.cookies;
80+
if (!getCookieValueByKey('__zse_ck')) {
81+
const zseCk = await cache.tryGet('zhihu:zse_ck', async () => {
82+
const response = await ofetch.raw('https://static.zhihu.com/zse-ck/v3.js');
83+
const script = await response._data.text();
84+
return script.match(/__g\.ck\|\|"([\w+/=\\]*?)",_=/)?.[1] || '';
85+
});
86+
if (zseCk) {
87+
cookieStr = `${cookieStr}; __zse_ck=${zseCk}`;
88+
}
89+
}
90+
7591
return {
76-
cookie: config.zhihu.cookies,
92+
cookie: cookieStr,
7793
'x-zse-96': xzse96,
7894
'x-app-za': 'OS=Web',
7995
'x-zse-93': xzse93,

0 commit comments

Comments
 (0)