浏览器环境LinkedIn登录Set-Cookie返回null,Node环境正常
我用代码实现LinkedIn登录,后续需要用到jsession id,但在浏览器环境里调用response.headers.get('Set-Cookie')返回null,Node.js环境下却能正常获取。相关代码如下:
(async () => { const loginPageResponse = await fetch('https://www.linkedin.com/home'); const loginPageHtml = await loginPageResponse.text(); const loginCsrfParamMatches = loginPageHtml.match(/name="loginCsrfParam" value="([^"]+)"/); const loginCsrfParam = loginCsrfParamMatches && loginCsrfParamMatches[1]; const loginFormData = new URLSearchParams(); loginFormData.append('session_key', 'username'); loginFormData.append('session_password', 'password'); loginFormData.append('loginCsrfParam', loginCsrfParam); const loginResponse = await fetch('https://www.linkedin.com/uas/login-submit', { method: 'POST', body: loginFormData, credentials:"include", headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': '*/*', 'Referer': 'https://www.linkedin.com/login', "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" }, redirect: 'manual' }); const jsessionId = loginResponse.headers.get('Set-Cookie') console.log(jsessionId); const jId = jsessionId.match(/ajax:\d+/)[0]; console.log(jId); const companyResponse = await fetch("api_endpoints"+"company_name",{ method: 'GET', headers: { 'Content-Type': 'application/json', "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", "csrf-token": jId, } }) })();
原因分析
这是浏览器的安全机制限制导致的:
- HttpOnly Cookie:LinkedIn设置的JSESSIONID通常带有
HttpOnly标记,浏览器禁止前端JavaScript直接访问这类Cookie,目的是防止XSS攻击窃取会话凭证。 - 同源策略:如果你的页面域名和LinkedIn不同(跨域场景),即使Cookie没有HttpOnly标记,浏览器也会限制前端读取响应头里的
Set-Cookie,这是同源策略的一部分。
Node.js作为服务器端环境,不受浏览器这些安全规则约束,因此可以正常获取Set-Cookie头。
解决方案
1. 依赖浏览器自动管理Cookie
不需要手动读取Set-Cookie,浏览器会自动处理Cookie的存储和携带:
- 确保所有fetch请求都设置
credentials: "include"(你代码里已经配置了登录请求的该参数),浏览器会自动将登录后的Cookie(包括JSESSIONID)存储起来。 - 后续请求LinkedIn API时,同样带上
credentials: "include",浏览器会自动把对应的Cookie附加到请求头中,无需手动提取和设置。
修改后的代码示例:
(async () => { const loginPageResponse = await fetch('https://www.linkedin.com/home'); const loginPageHtml = await loginPageResponse.text(); const loginCsrfParamMatches = loginPageHtml.match(/name="loginCsrfParam" value="([^"]+)"/); const loginCsrfParam = loginCsrfParamMatches && loginCsrfParamMatches[1]; const loginFormData = new URLSearchParams(); loginFormData.append('session_key', 'username'); loginFormData.append('session_password', 'password'); loginFormData.append('loginCsrfParam', loginCsrfParam); // 登录请求,浏览器自动存储Cookie const loginResponse = await fetch('https://www.linkedin.com/uas/login-submit', { method: 'POST', body: loginFormData, credentials: "include", headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': '*/*', 'Referer': 'https://www.linkedin.com/login', "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" }, redirect: 'manual' }); // 后续API请求,浏览器自动携带Cookie const companyResponse = await fetch("api_endpoints"+"company_name",{ method: 'GET', credentials: "include", // 关键:让浏览器自动附加Cookie headers: { 'Content-Type': 'application/json', "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" } }); const companyData = await companyResponse.json(); console.log(companyData); })();
2. 关于CSRF Token的处理
如果后续API仍需要csrf-token,可以尝试:
- 从登录后的页面HTML中提取(类似之前提取
loginCsrfParam的方式); - 读取
document.cookie中未标记为HttpOnly的csrf相关Cookie(如果LinkedIn提供)。
重要注意事项
LinkedIn有严格的反爬虫和账号安全机制,这种前端模拟登录的方式很容易触发风控,导致账号被限制或封禁。建议优先使用LinkedIn官方提供的OAuth2认证流程进行合法的API调用。
内容的提问来源于stack exchange,提问作者ks_
相关产品推荐
相关产品推荐

