|
|
@@ -2593,6 +2593,31 @@ async function collectBaijiahaoAccountInfo() {
|
|
|
};
|
|
|
|
|
|
console.log('[百家号] 完整账号信息:', accountInfo.value);
|
|
|
+ // 关键:在完整流程结束后再抓一次 Cookie,避免过早抓取导致关键 Cookie 不全
|
|
|
+ console.log('[百家号] 步骤4: 刷新并保存最终 Cookie...');
|
|
|
+ try {
|
|
|
+ const currentUrl = webview.getURL?.() || '';
|
|
|
+ if (!currentUrl.includes('/builder/rc/home')) {
|
|
|
+ webview.loadURL('https://baijiahao.baidu.com/builder/rc/home');
|
|
|
+ await waitForPageLoad(webview, 5000);
|
|
|
+ }
|
|
|
+ await sleep(1500);
|
|
|
+ await getCookieData();
|
|
|
+
|
|
|
+ try {
|
|
|
+ const parsed = JSON.parse(cookieData.value || '[]');
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ const names = parsed.map((c: any) => c?.name).filter(Boolean);
|
|
|
+ const mustHave = ['BDUSS', 'STOKEN', 'bjhStoken', 'devStoken'];
|
|
|
+ const present = mustHave.filter(name => names.includes(name));
|
|
|
+ console.log(`[百家号] 最终 Cookie 数量: ${parsed.length}, 关键 Cookie: ${present.join(', ') || '无'}`);
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('[百家号] 最终 Cookie 刷新失败,继续保存当前结果:', error);
|
|
|
+ }
|
|
|
showSuccessMessage();
|
|
|
}
|
|
|
|
|
|
@@ -3732,15 +3757,82 @@ async function getCookies(): Promise<Electron.Cookie[]> {
|
|
|
|
|
|
const platformInfo = PLATFORMS[platform.value];
|
|
|
if (!platformInfo) return [];
|
|
|
-
|
|
|
- // 获取登录域名的 cookies
|
|
|
- const url = platformInfo.loginUrl;
|
|
|
- return await window.electronAPI.getWebviewCookies(webviewPartition.value, url);
|
|
|
+
|
|
|
+ // 百家号需要聚合多个 URL 下的 Cookie,避免仅登录页路径导致关键 Cookie 丢失
|
|
|
+ if (platform.value === 'baijiahao') {
|
|
|
+ // 优先走 partition 全量 Cookie,避免 URL/path 过滤导致 Cookie 不全
|
|
|
+ if (window.electronAPI.getWebviewAllCookies) {
|
|
|
+ try {
|
|
|
+ const allCookies = await window.electronAPI.getWebviewAllCookies(webviewPartition.value);
|
|
|
+ const baiduCookies = allCookies.filter(cookie => {
|
|
|
+ const domain = String(cookie.domain || '').toLowerCase();
|
|
|
+ return domain.includes('baidu.com');
|
|
|
+ });
|
|
|
+
|
|
|
+ if (baiduCookies.length > 0) {
|
|
|
+ const merged = new Map<string, Electron.Cookie>();
|
|
|
+ for (const cookie of baiduCookies) {
|
|
|
+ const key = `${cookie.name}|${cookie.domain}|${cookie.path}`;
|
|
|
+ merged.set(key, cookie);
|
|
|
+ }
|
|
|
+ console.log(`[getCookies] 百家号从 partition 全量获取到 ${merged.size} 个 baidu Cookie`);
|
|
|
+ return Array.from(merged.values());
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('[getCookies] getWebviewAllCookies 失败,回退 URL 聚合:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 回退:按多个 URL 聚合
|
|
|
+ const urls = [
|
|
|
+ platformInfo.creatorUrl,
|
|
|
+ platformInfo.loginUrl,
|
|
|
+ 'https://baijiahao.baidu.com/builder/rc/content',
|
|
|
+ 'https://passport.baidu.com/',
|
|
|
+ 'https://hm.baidu.com/',
|
|
|
+ 'https://www.baidu.com/',
|
|
|
+ ];
|
|
|
+
|
|
|
+ const cookieLists = await Promise.all(
|
|
|
+ urls.map(async (url) => {
|
|
|
+ try {
|
|
|
+ return await window.electronAPI.getWebviewCookies(webviewPartition.value, url);
|
|
|
+ } catch (error) {
|
|
|
+ console.warn(`[getCookies] 获取 Cookie 失败: ${url}`, error);
|
|
|
+ return [] as Electron.Cookie[];
|
|
|
+ }
|
|
|
+ })
|
|
|
+ );
|
|
|
+
|
|
|
+ const merged = new Map<string, Electron.Cookie>();
|
|
|
+ for (const list of cookieLists) {
|
|
|
+ for (const cookie of list) {
|
|
|
+ const key = `${cookie.name}|${cookie.domain}|${cookie.path}`;
|
|
|
+ merged.set(key, cookie);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Array.from(merged.values());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他平台按登录 URL 获取即可
|
|
|
+ return await window.electronAPI.getWebviewCookies(webviewPartition.value, platformInfo.loginUrl);
|
|
|
}
|
|
|
|
|
|
// 格式化 cookies 为字符串
|
|
|
function formatCookies(cookies: Electron.Cookie[]): string {
|
|
|
- return cookies.map(c => `${c.name}=${c.value}`).join('; ');
|
|
|
+ // 保存完整 cookie 属性,避免后台再次注入时丢失 domain/path/sameSite 等信息
|
|
|
+ const normalized = cookies.map(cookie => ({
|
|
|
+ name: cookie.name,
|
|
|
+ value: cookie.value,
|
|
|
+ domain: cookie.domain,
|
|
|
+ path: cookie.path || '/',
|
|
|
+ expires: cookie.expirationDate,
|
|
|
+ httpOnly: cookie.httpOnly,
|
|
|
+ secure: cookie.secure,
|
|
|
+ sameSite: cookie.sameSite,
|
|
|
+ }));
|
|
|
+
|
|
|
+ return JSON.stringify(normalized);
|
|
|
}
|
|
|
|
|
|
// 手动检测登录(使用 URL 检测)
|
|
|
@@ -3887,12 +3979,35 @@ async function setPresetCookies(cookieDataStr: string) {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
+ type PresetCookie = {
|
|
|
+ name: string;
|
|
|
+ value: string;
|
|
|
+ domain?: string;
|
|
|
+ path?: string;
|
|
|
+ expires?: number | string;
|
|
|
+ expirationDate?: number | string;
|
|
|
+ httpOnly?: boolean;
|
|
|
+ secure?: boolean;
|
|
|
+ sameSite?: string;
|
|
|
+ };
|
|
|
+
|
|
|
// 尝试解析 JSON 格式的 cookie
|
|
|
- let cookieList: Array<{ name: string; value: string; domain?: string; path?: string; expires?: number }>;
|
|
|
+ let cookieList: PresetCookie[];
|
|
|
|
|
|
try {
|
|
|
- cookieList = JSON.parse(cookieDataStr);
|
|
|
- console.log('[BrowserTab] 成功解析 JSON 格式的 Cookie');
|
|
|
+ const parsed = JSON.parse(cookieDataStr) as PresetCookie[] | { cookies?: PresetCookie[] } | PresetCookie;
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ cookieList = parsed;
|
|
|
+ console.log('[BrowserTab] 成功解析 JSON 数组格式的 Cookie');
|
|
|
+ } else if (parsed && Array.isArray((parsed as { cookies?: PresetCookie[] }).cookies)) {
|
|
|
+ cookieList = (parsed as { cookies: PresetCookie[] }).cookies;
|
|
|
+ console.log('[BrowserTab] 成功解析 storageState 格式的 Cookie');
|
|
|
+ } else if (parsed && typeof parsed === 'object' && 'name' in parsed && 'value' in parsed) {
|
|
|
+ cookieList = [parsed as PresetCookie];
|
|
|
+ console.log('[BrowserTab] 成功解析单个 Cookie 对象');
|
|
|
+ } else {
|
|
|
+ throw new Error('Unsupported cookie JSON format');
|
|
|
+ }
|
|
|
} catch {
|
|
|
// 如果不是 JSON,尝试解析 "name=value; name2=value2" 格式
|
|
|
console.log('[BrowserTab] JSON 解析失败,尝试解析字符串格式');
|
|
|
@@ -3924,18 +4039,46 @@ async function setPresetCookies(cookieDataStr: string) {
|
|
|
const cookieUrl = platform.value === 'baijiahao'
|
|
|
? 'https://www.baidu.com'
|
|
|
: targetUrl;
|
|
|
+
|
|
|
+ // 根据 cookie 域名选择更匹配的 URL(避免 URL 与 domain 不匹配导致设置失败)
|
|
|
+ const resolveCookieUrl = (domain?: string): string => {
|
|
|
+ if (platform.value !== 'baijiahao') {
|
|
|
+ return cookieUrl;
|
|
|
+ }
|
|
|
+
|
|
|
+ const normalizedDomain = String(domain || '').replace(/^\./, '').toLowerCase();
|
|
|
+ if (!normalizedDomain) return cookieUrl;
|
|
|
+
|
|
|
+ if (normalizedDomain.includes('baijiahao.baidu.com')) return 'https://baijiahao.baidu.com';
|
|
|
+ if (normalizedDomain.includes('passport.baidu.com')) return 'https://passport.baidu.com';
|
|
|
+ if (normalizedDomain.includes('hm.baidu.com')) return 'https://hm.baidu.com';
|
|
|
+ if (normalizedDomain.endsWith('baidu.com')) return 'https://www.baidu.com';
|
|
|
+
|
|
|
+ return cookieUrl;
|
|
|
+ };
|
|
|
|
|
|
console.log(`[BrowserTab] 设置 Cookie, platform=${platform.value}, targetUrl=${targetUrl}, cookieUrl=${cookieUrl}, domain=${rootDomain}`);
|
|
|
console.log(`[BrowserTab] Cookie 列表:`, cookieList.slice(0, 3).map(c => ({ name: c.name, domain: c.domain })));
|
|
|
|
|
|
+ // 提取有效的过期时间(秒);<= 0 视为会话 Cookie(不应当作过期)
|
|
|
+ const getCookieExpires = (cookie: PresetCookie): number | undefined => {
|
|
|
+ const raw = cookie.expires ?? cookie.expirationDate;
|
|
|
+ if (raw === undefined || raw === null || raw === '') return undefined;
|
|
|
+ const expires = Number(raw);
|
|
|
+ if (!Number.isFinite(expires)) return undefined;
|
|
|
+ if (expires <= 0) return undefined; // Playwright/session cookie 常用 -1
|
|
|
+ return expires;
|
|
|
+ };
|
|
|
+
|
|
|
// 过滤掉已过期的 Cookie
|
|
|
const now = Date.now() / 1000;
|
|
|
const validCookies = cookieList.filter(cookie => {
|
|
|
- if (cookie.expires && cookie.expires < now) {
|
|
|
+ const expires = getCookieExpires(cookie);
|
|
|
+ if (expires && expires < now) {
|
|
|
console.warn(`[BrowserTab] Cookie ${cookie.name} 已过期,跳过`);
|
|
|
return false;
|
|
|
}
|
|
|
- return true;
|
|
|
+ return !!cookie.name && cookie.value !== undefined && cookie.value !== null;
|
|
|
});
|
|
|
|
|
|
if (validCookies.length === 0) {
|
|
|
@@ -3961,7 +4104,7 @@ async function setPresetCookies(cookieDataStr: string) {
|
|
|
}
|
|
|
|
|
|
const electronCookie: any = {
|
|
|
- url: cookieUrl, // 使用正确的 URL
|
|
|
+ url: resolveCookieUrl(cookieDomain), // 使用与 domain 匹配的 URL
|
|
|
name: cookie.name,
|
|
|
value: cookie.value,
|
|
|
domain: cookieDomain,
|
|
|
@@ -3969,8 +4112,9 @@ async function setPresetCookies(cookieDataStr: string) {
|
|
|
};
|
|
|
|
|
|
// 添加可选字段
|
|
|
- if (cookie.expires) {
|
|
|
- electronCookie.expirationDate = cookie.expires;
|
|
|
+ const expires = getCookieExpires(cookie);
|
|
|
+ if (expires) {
|
|
|
+ electronCookie.expirationDate = expires;
|
|
|
}
|
|
|
if ((cookie as any).httpOnly !== undefined) {
|
|
|
electronCookie.httpOnly = (cookie as any).httpOnly;
|
|
|
@@ -3981,11 +4125,16 @@ async function setPresetCookies(cookieDataStr: string) {
|
|
|
if ((cookie as any).sameSite) {
|
|
|
// 转换 sameSite 值
|
|
|
const sameSite = (cookie as any).sameSite;
|
|
|
- if (sameSite === 'None') {
|
|
|
+ const normalizedSameSite = String(sameSite).toLowerCase();
|
|
|
+ if (normalizedSameSite === 'none' || normalizedSameSite === 'no_restriction') {
|
|
|
electronCookie.sameSite = 'no_restriction';
|
|
|
- } else if (sameSite === 'Lax' || sameSite === 'lax') {
|
|
|
+ // no_restriction 需要 secure=true,否则部分 Chromium 版本会拒绝设置
|
|
|
+ if (electronCookie.secure !== true) {
|
|
|
+ electronCookie.secure = true;
|
|
|
+ }
|
|
|
+ } else if (normalizedSameSite === 'lax') {
|
|
|
electronCookie.sameSite = 'lax';
|
|
|
- } else if (sameSite === 'Strict' || sameSite === 'strict') {
|
|
|
+ } else if (normalizedSameSite === 'strict') {
|
|
|
electronCookie.sameSite = 'strict';
|
|
|
}
|
|
|
}
|