Django嵌入跨域PHP iframe时的CSRF替代方案及安全性疑问
问题描述
我将Django应用嵌入到另一台服务器托管的PHP页面的iframe中,除POST请求外其余功能均正常,仅在Firefox中出现403报错:
Request failed with status code 403 > CSRF verification failed > CSRF cookie not set
此前存在SameSite警告(Some cookies are misusing the recommended “SameSite“ attribute),我已通过PHP脚本解决该警告:
PHP配置
ini_set('session.cookie_httponly',1); ini_set('session.use_only_cookies',1); $cookieParams = session_get_cookie_params(); $cookieParams[samesite] = "None"; $cookieParams[secure] = true; session_set_cookie_params($cookieParams); session_start();
警告已消除,但Cookie仍无法在iframe中传递(Chrome中正常)。我尝试通过Axios手动携带CSRF Token:
JS配置
axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"; const config = { headers: { 'method':'POST', 'accept': '*/*', 'content-type': 'application/json;charset=UTF-8', withCredentials: true, 'X-CSRFTOKEN': window.csrf_token, //csrfmiddlewaretoken: window.csrf_token } }; axios.post(url, datas, config).then((res) => {....
同时在Django的Settings.py中配置:
Django Settings配置
CSRF_TRUSTED_ORIGINS = ['https://myPhpsite.com', 'myPhpsite.com'] CSRF_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True SESSION_COOKIE_SAMESITE = 'None' CORS_ALLOW_CREDENTIALS = True
但问题仍未解决,目前我考虑注释掉django.middleware.csrf.CsrfViewMiddleware来禁用CSRF防护,请问这样做能否达到与CSRF防护相同的安全效果?
回答
绝对不能。禁用CSRF防护会直接移除Django默认的跨站请求伪造防护机制,完全失去对应的安全能力,和保留CSRF防护的安全效果天差地别。
你当前的问题是Firefox下Cookie传递异常导致的CSRF验证失败,而非CSRF防护本身有问题,禁用它属于典型的“因噎废食”。针对当前问题,还可以尝试这些排查方向:
- 检查Firefox隐私设置:如果开启了「增强型跟踪保护」,可能会拦截跨域iframe的Cookie传递,可临时关闭该功能测试。
- 修正
CSRF_TRUSTED_ORIGINS格式:必须带完整的协议+域名,比如仅保留https://myPhpsite.com,避免纯域名导致匹配失败。 - 调整Axios配置中
withCredentials的位置:你把它写在headers子项里是错误的,它应该是config的顶层属性,正确写法如下:
const config = { headers: { 'accept': '*/*', 'content-type': 'application/json;charset=UTF-8', 'X-CSRFTOKEN': window.csrf_token }, withCredentials: true // 移至顶层 };
- 验证
window.csrf_token的正确性:在浏览器控制台打印该值,确认它和Django返回的csrftoken Cookie值完全一致。
内容的提问来源于stack exchange,提问作者Zorro
相关产品推荐
相关产品推荐

