MERN应用Vercel+Heroku部署后Set-Cookie已发送但前端未存储
问题根因及解决方案
1. 前端存储面板看不到Cookie的说明
你设置了httpOnly: true的Cookie是安全配置,本身就是为了防止XSS攻击窃取凭证,前端JS无法读取属于正常现象。
你在前端Vercel域名的存储面板看不到该Cookie是因为Cookie归属在Heroku后端域名下,需要打开浏览器的「所有Cookie和站点数据」面板,找到后端Heroku域名对应的条目即可查看,不存在安全隐患。
2. Safari浏览器自动登出的核心原因
前端部署在Vercel、后端部署在Heroku属于跨域名场景,你设置的sameSite: noneCookie属于第三方Cookie,Safari的智能跟踪预防(ITP)策略默认会拦截所有第三方持久化Cookie,哪怕你配置了secure: true也无法规避,这是Safari的默认安全策略导致的。
3. 登出接口的遗留隐患修复
你目前的登出接口只调用了clearCookie('token'),没有传入和设置Cookie时完全一致的属性参数,浏览器可能无法正确匹配要删除的Cookie,之前的修复只是解决了前端响应判定问题,属性缺失的隐患仍然存在,需要修改为以下配置:
import type Route from '../../types/Route' import authorization from '../../middlewares/http' import env from '../../env/env' const route: Route = { method: 'get', authorization, execute: async (req, res) => { try { return res.clearCookie('token', { expires: new Date(Date.now() + 604800000), secure: env.ENVIRONMENT === 'LIVE', sameSite: env.ENVIRONMENT === 'LIVE' ? 'none' : 'lax', httpOnly: true }).send({ message: 'Sign Out Successful' }) } catch (error) { console.log('@sign/out', error) return res.status(500).send({ error: 'Sign out failed' }) } } } export default route
根治方案推荐
最优解是给后端绑定和前端同根的子域名,比如前端用yourdomain.com,后端绑定api.yourdomain.com,此时前后端属于同站场景,不需要再配置sameSite: none,改为sameSite: lax即可,自动绕开Safari第三方Cookie拦截规则,同时前端存储面板也可以直接在当前域名下看到对应Cookie。
如果暂时无法调整域名,只能引导Safari用户手动开启第三方Cookie权限,但该方案用户操作成本极高,不推荐使用。
内容的提问来源于stack exchange,提问作者Norah

