生产环境不同域名场景下如何收发Cookie?附已尝试的配置代码
问题修复步骤
- 移除冗余的CORS配置
你同时使用了cors中间件和手动设置Access-Control-*响应头,重复配置会导致浏览器识别异常,直接删除所有app.set('Access-Control-*')相关的代码即可,cors中间件会自动处理这些响应头。 - 对齐两处Cookie的配置
你现在同时设置了两个Cookie:csurf内部生成的_csrfCookie,以及你手动设置的XSRF-TOKENCookie,两者的属性必须完全对齐才能正常生效,调整代码如下:
const csrfProtection =csrf({ cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 生产环境如果有固定域名可以加上domain配置,比如domain: '.yourdomain.com' }, }); // 手动设置XSRF-TOKEN时属性保持和上面一致 app.get('/', csrfProtection, (req: Request, res: Response) => { res.cookie('XSRF-TOKEN', req.csrfToken(), { httpOnly: false, // 这个Cookie需要给前端JS读取,所以不能开httpOnly secure: process.env.NODE_ENV === 'production', sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 同上,生产环境可加domain配置 }); res.send('success!'); });
- 确认生产环境变量配置
登录Heroku后台检查环境变量,确保NODE_ENV值为production,同时CLIENT_ORIGIN要填你Vercel部署的完整域名(比如https://your-next-app.vercel.app,不要漏https前缀)。 - 补全axios的CSRF配置
给你的自定义axios实例加上显式的CSRF配置,避免默认值不匹配:
const axiosInstance = Axios.create({ baseURL, withCredentials: true, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN' });
替代方案(不需要跨域Cookie)
如果调整后还是存在兼容性问题,可以采用无Cookie的CSRF防护方案:
- 第一次请求CSRF令牌时,不将令牌存在Cookie里,直接放在响应体返回给前端
- 前端将令牌存在localStorage中,之后每次请求都将令牌放在
X-XSRF-TOKEN请求头中携带 - 调整
csurf配置,指定从请求头读取令牌即可,完全规避跨域Cookie的限制。
内容的提问来源于stack exchange,提问作者aviram
相关产品推荐
相关产品推荐

