jim*_*man 5 django ajax jquery django-csrf reactjs
我正在开发一个使用Django REST框架作为后端的项目(让我们说api.somecompany.com但是有一个React.js前端(at www.somecompany.com)不是由Django提供的,它提出了AJAX请求.
因此,我不能使用Django的传统方法让模板包含这样的CSRF令牌 <form action="." method="post">{% csrf_token %}
我可以向Django REST Framework的api-auth\login\url 发出请求,它会返回这个标题:
Set-Cookie:csrftoken=tjQfRZXWW4GtnWfe5fhTYor7uWnAYqhz; expires=Mon, 01-Aug-2016 16:32:10 GMT; Max-Age=31449600; Path=/- 但是我无法检索这个cookie以发回我的AJAX请求X-CSRFToken(我的理解是单独的子域),它不会似乎被自动包括在内.
这是我的相关代码:
// using jQuery
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
Run Code Online (Sandbox Code Playgroud)
当页面加载时我调用它以确保我有一个令牌:
$.ajax(loginUrl, { method: "OPTIONS", async: false })
.done(function(data, textStatus, jqXHR) {
console.log(jqXHR)
app.csrftoken@ = $.cookie("csrftoken")
console.log($.cookie("csrftoken"))
console.log(app.csrftoken)
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
});
Run Code Online (Sandbox Code Playgroud)
这不是很干净,但我还没有向自己证明这个概念.
当前端和后端位于不同的端口/域上时,对CSRF进行身份验证/保护的"正确"方法是什么?
事实上,您可以使用允许的请求来源白名单,使其与 CSRF 保护一起工作。
要实现此功能,您必须使用Cross-Origin Resource Sharing(CORS)。为了实现这一目标,我建议创建一个中间件类来设置交叉共享凭据。有一个很好的要点概述了如何使用跨源 HTTP 请求标头中的一些构建。如果需要,您可以通过更改请求的原始引用值,以这种方式通过中间件插入 CSRF 令牌。
django-cors-headers应用程序可以为您完成此操作。如果您感兴趣,您可以了解他们如何在中间件文件中协商 CSRF 令牌。
有关更多信息,请参阅Django REST CORS 文档(他们建议使用 django-cors-headers)。
如果您仍然遇到困难,请尝试:
crossDomainAJAX 请求的参数设置为True. 有时,如果未指定,jQuery 将不会处理请求。ensure_csrf_cookie()在视图方法周围附加装饰器。有时,当页面上没有{% csrf_token %}模板标记时(如果您没有渲染表单),Django 根本不会在请求中包含令牌。| 归档时间: |
|
| 查看次数: |
1655 次 |
| 最近记录: |