Django附带了CSRF保护中间件,它可以生成一个独特的每会话令牌,用于表单.它会扫描所有传入的POST
请求以获取正确的令牌,并在令牌丢失或无效时拒绝该请求.
我想将AJAX用于一些POST请求,但是所述请求没有CSRF令牌可供选择.页面没有可以挂钩的元素,我宁愿不把标记作为隐藏值插入标记.我认为这样做的一个好方法是公开一个
/get-csrf-token/
想要返回用户令牌的vew ,依靠浏览器的跨站点脚本规则来防止恶意站点请求它.
这是一个好主意吗?是否有更好的方法来防止CSRF攻击,同时仍允许AJAX请求?
更新:以下是真的,如果所有浏览器和插件都正确实现,应该是真的.不幸的是,我们现在知道它们不是,并且浏览器插件和重定向的某些组合可以允许攻击者在跨域请求上提供任意标头.不幸的是,这意味着即使带有"X-Requested-With:XMLHttpRequest"标头的AJAX请求现在也必须受CSRF保护.因此,Django 不再免除来自CSRF保护的Ajax请求.
原始答案
值得一提的是,保护来自CSRF的AJAX请求是不必要的,因为浏览器不允许跨站点AJAX请求.实际上,Django CSRF中间件现在可以自动免除来自CSRF令牌扫描的AJAX请求.
这仅在您实际检查X-Requested-With标头服务器端的"XMLHttpRequest"值(Django所做的)时才有效,并且只从CSRF扫描中免除真正的AJAX请求.
如果你知道你需要为AJAX请求提供CSRF令牌,你可以随时将它嵌入到某个地方的HTML中; 然后你可以通过遍历DOM找到它.这样,您仍然可以访问令牌,但您不会通过API公开它.
换句话说:通过Django的模板 - 而不是通过URL调度程序.这种方式更加安全.