如何在javascript中对具有csrf保护的django框架进行正确的ajax调用?
Posted
技术标签:
【中文标题】如何在javascript中对具有csrf保护的django框架进行正确的ajax调用?【英文标题】:how to make a proper ajax call in javascript to django framework with csrf protection? 【发布时间】:2015-12-24 05:08:33 【问题描述】:在将其标记为重复之前,请仔细阅读,因为我已经经历了很多堆栈溢出问题,但找不到合适的解决方案。
所以我面临的问题是我是 django 的新手,并且了解了 POST 请求的 CSRF 保护。我已经在基于非 ajax 的页面上成功实现了这些调用。但是我正在处理的当前项目是一个单页应用程序。所以所有的调用都是通过 ajax 并且在 vanila JS 中不使用任何库。我面临的问题是,对于第一个请求,我获得了在模板中生成的有效 CSRF 令牌。但是在第一次 ajax 调用之后 CSRF 令牌发生了变化。所以我想知道在这种情况下,django 中的正确方法是什么。我应该以某种方式让所有请求都以 CSRF 令牌响应并将它们保存在 JS 变量中吗?
目前还有两个页面。第一个是没有 ajax 调用的简单登录模板。它使用凭据发布到主页,如果有效,则完成。但在家里有多种形式。并且提交其中任何一个都会更改令牌,所以我该如何处理这样的情况。
PS:我更喜欢纯 JS 中的代码而不是 jquery 或任何其他框架,并且不想禁用 csrf 保护。
我已经认为将 CSRF 令牌存储在 cookie 或会话变量中,这将违背令牌的全部目的。
请附上我可以学习的示例代码。
【问题讨论】:
是的,您应该将其存储在 JS 变量中并与 ajax 请求一起发送。您到底尝试过哪些不起作用的方法? @dan-klasson 我没有尝试过,但想知道正确的处理方式。如果基于 ajax 的表单与普通表单混合,这种情况会怎样。这种情况下的解决方案是什么? 【参考方案1】:我面临的问题是我收到的第一个请求 我在模板中生成的有效 CSRF 令牌。但之后 首先 ajax 调用 CSRF 令牌更改。
我不相信这是真的。否则,如果用户打开多个选项卡,任何 django 应用程序都会停止工作。
这是我在网络应用上使用的解决方案。它按预期工作,但我没有遵循从 cookie 中获取令牌值的官方建议。为什么?更少的代码。
myapp/templatetags/csrf_ajax.html
from django import template
register = template.Library()
@register.inclusion_tag('myapp/_csrf_ajax.html')
def csrf_ajax():
# https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax
return
_csrf_ajax.html
<script>
(function ()
var csrf_token = " csrf_token ";
function csrfSafeMethod(method)
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
$.ajaxSetup(
beforeSend: function(xhr, settings)
if (!csrfSafeMethod(settings.type) && !this.crossDomain)
xhr.setRequestHeader("X-CSRFToken", csrf_token);
);
)();
</script>
然后我在每个需要 CSRF ajax 设置的页面中使用这个模板标签。
% csrf_ajax %
【讨论】:
【参考方案2】:csrttoken 存储在 cookie 中,它不会随着每个 ajax 请求而改变。我在 js 文件中有这段代码,并将其添加到需要发送 ajax 发布请求的任何页面(它使用 jQuery 和 cookie,如果您不想使用外部库,则需要将其转换为纯 javascript):
var csrftoken = $.cookie('csrftoken');
function csrfSafeMethod(method)
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
$.ajaxSetup(
beforeSend: function(xhr, settings)
if (!csrfSafeMethod(settings.type) && !this.crossDomain)
xhr.setRequestHeader("X-CSRFToken", csrftoken);
);
【讨论】:
以上是关于如何在javascript中对具有csrf保护的django框架进行正确的ajax调用?的主要内容,如果未能解决你的问题,请参考以下文章
Django中的X-editable内联编辑-如何获得CSRF保护?
保护 oauth 不记名令牌免受 javascript 应用程序中的 XSS、CSRF 等攻击
如何绕过csrf保护,并在burp suite中使用intruder?