Django开发环境下Safari与Firefox无法保存Cookie问题求助
问题背景
- 开发环境使用Cookie存储token和CSRF Token,Firefox和Safari的存储面板无法显示已设置的Cookie,即使关闭Safari的「阻止跨站跟踪」选项也无改善
- 虽面板看不到Cookie,但登录后API请求能正常携带Cookie访问资源,登录响应头如下:
Response
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://localhost:3000
Access-Control-Expose-Headers: Content-Type, X-CSRFToken
Allow: POST, OPTIONS
Connection: close
Content-Length: 714
Content-Type: application/json
Cross-Origin-Opener-Policy: same-origin
Date: Tue, 18 Apr 2023 17:11:05 GMT
Referrer-Policy: same-origin
Server: Werkzeug/2.2.3 Python/3.9.6
Set-Cookie: auth1=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9; expires=Tue, 18 Apr 2023 17:21:05 GMT; HttpOnly; Max-Age=600; Path=/; SameSite=None; Secure
Set-Cookie: csrftoken=Y1GzI80DfRc3lMkUnboTYeA3AZBY4aih; expires=Tue, 16 Apr 2024 17:11:05 GMT; Max-Age=31449600; Path=/; Secure
Vary: Accept, Cookie, Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
- 技术栈:Django后端、React前端,均运行在localhost但不同端口,且都通过HTTPS访问
- 其他浏览器表现:Chrome可正常显示Cookie;Edge能保存但刷新后丢失,与Firefox类似
- 疑问:开发环境能否解决该问题实现全浏览器测试?如何在localhost模拟同域名子域?是否必须部署才能测试?
Cookie设置代码:
response.set_cookie('auth1', token_header, httponly=True, samesite='None', secure=True, max_age=600)
解决方法
1. 本地模拟同域名子域(无需部署)
浏览器将不同端口视为跨域,但同一主域的子域不属于跨域,可通过修改本地hosts文件实现:
- 修改hosts文件:
- Windows:打开
C:\Windows\System32\drivers\etc\hosts,添加两行:127.0.0.1 api.localhost 127.0.0.1 app.localhost - Mac/Linux:打开
/etc/hosts,添加上述两行
- Windows:打开
- 后端配置:
- Django的
ALLOWED_HOSTS中加入api.localhost - 启动后端时绑定到该子域:
python manage.py runserver api.localhost:8000,同时确保HTTPS配置对应此域名
- Django的
- 前端配置:
- 将API请求地址改为
https://api.localhost:8000 - 启动React时绑定到
app.localhost:3000
- 将API请求地址改为
- 此方法下前后端同属
localhost主域,浏览器会正常识别并显示Cookie
2. 调整浏览器隐私设置(仅用于本地测试)
- Firefox:
- 地址栏输入
about:config,确认风险提示 - 搜索
network.cookie.sameSite.laxByDefault,设置为false - 搜索
network.cookie.sameSite.noneRequiresSecure,确保值为true(你的Cookie已添加Secure属性,符合要求)
- 地址栏输入
- Safari:
- 开启开发菜单:偏好设置 → 高级 → 勾选「显示开发菜单」
- 开发菜单中选择「禁用跨域限制」
- 同时关闭隐私设置中的「阻止跨站跟踪」
3. 检查Cookie及CORS配置细节
- 确保
SameSite=None与Secure属性同时存在(你已正确设置) - 后端
Access-Control-Allow-Origin必须指定具体前端域名,不能用通配符*(你已设置为https://localhost:3000,符合要求) - 前端请求需携带
credentials: 'include':比如Axios设置withCredentials: true,Fetch请求添加credentials: 'include'参数
4. 修复Edge刷新丢失Cookie问题
Edge基于Chromium内核,刷新丢失Cookie可能是以下原因:
- 检查Edge隐私设置,是否开启了「关闭浏览器时清除Cookie和网站数据」
- 确认Cookie的
max_age或expires设置正确,你设置的max_age=600是10分钟,属于持久化Cookie,若仍丢失可尝试明确设置expires参数
内容的提问来源于stack exchange,提问作者Ran123

