Django旧版本(≤3.2)默认SESSION_COOKIE_HTTPONLY=False,使JavaScript可读sessionid,XSS攻击下易导致会话劫持;修复需同时设SESSION_COOKIE_HTTPONLY=True、SESSION_COOKIE_SECURE=True(HTTPS环境)和SESSION_COOKIE_SAMESITE='Lax'。

必须在框架层显式设置 Secure、HttpOnly 和 SameSite 三个属性,缺一不可;只设其中一两个,等于没设。
为什么 Django 的 SESSION_COOKIE_HTTPONLY 默认是 False
Django 旧版本(≤3.2)默认未开启 SESSION_COOKIE_HTTPONLY,意味着 JavaScript 可通过 document.cookie 直接读取 sessionid。一旦页面存在 XSS 漏洞,攻击者就能窃取并复用该值——相当于把用户登录态白送出去。
修复只需一行:
SESSION_COOKIE_HTTPONLY = True
但注意:这行单独存在没用,必须配套以下两点才真正生效:
立即学习“Python免费学习笔记(深入)”;
-
SESSION_COOKIE_SECURE = True(生产环境 HTTPS 必须启用,否则浏览器会忽略 Cookie) -
SESSION_COOKIE_SAMESITE = 'Lax'(推荐值;若需 iframe 嵌入或 OAuth 回调,才考虑'None',但必须同时满足SESSION_COOKIE_SECURE = True)
Flask 中 SESSION_COOKIE_SAMESITE='None' 为什么总失效
直接写 SESSION_COOKIE_SAMESITE = 'None' 在 Safari ≤12.1 和部分旧版 Android WebView 中会静默丢弃 Cookie,用户无法登录,且无任何错误提示。
根本原因是这些浏览器不识别 SameSite=None,反而视其为非法值而拒绝存储。
正确做法是用 after_request 动态判断 UA 并降级:
@app.after_request
def set_samesite_cookie(response):
if response.headers.get('Set-Cookie'):
# 检查是否是旧版 Safari
ua = request.headers.get('User-Agent', '')
if 'Safari' in ua and 'Chrome' not in ua and int(ua.split('Version/')[1].split('.')[0]) < 13:
# 降级为 Lax
response.headers['Set-Cookie'] = response.headers['Set-Cookie'].replace(
'SameSite=None', 'SameSite=Lax'
)
return response更稳妥的方案是:只在明确需要跨站 POST 或 iframe 场景时才设 'None',其他情况一律用 'Lax'。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
FastAPI 设置 Cookie 时 samesite 参数大小写敏感吗
敏感。FastAPI 的 response.set_cookie() 方法中,samesite 参数只接受小写字符串:"lax"、"strict"、"none"。传 "Lax" 或 "None" 会导致该属性被完全忽略,浏览器按默认策略(现代浏览器默认为 Lax)处理,但行为不可控。
常见错误写法:
response.set_cookie(..., samesite="Lax") # ❌ 无效
正确写法:
response.set_cookie(..., samesite="lax") # ✅
另外注意:samesite="none" 必须搭配 secure=True,否则 Chrome/Firefox 会直接拒收该 Cookie,且不报错。
requests.Session 自动携带 Cookie 但不继承安全属性
requests.Session 会自动保存并发送服务器返回的 Cookie,但它**完全不解析也不校验** Secure、HttpOnly 或 SameSite 属性。也就是说,即使服务端设置了 Secure=True,Session 在 HTTP 请求中仍会照发——这在测试或代理调试时极易造成误判。
验证方式:抓包看请求头中的 Cookie 字段是否出现,而不是依赖响应头里的 Set-Cookie 属性是否齐全。
真实风险点:
- 本地开发用 HTTP 但服务端配了
Secure=True→ 浏览器不存 Cookie,但requests.Session仍能“假装”有状态,掩盖配置错误 - 自动化脚本绕过浏览器安全策略 → 无法反映真实终端行为,导致上线后大面积会话丢失
结论:不要用 requests 模拟来验证 Cookie 安全配置是否生效,必须用真实浏览器 + DevTools Application 标签页查看 Cookie 列表及其属性。

















