Я работаю над проектом, использующим Django REST Framework в качестве бэкэнд (скажем, в api.somecompany.com
, но имеет интерфейс React.js (по адресу www.somecompany.com
) не обслуживается Джанго, что делает AJAX запросы.Как получить/предоставить токен CSRF в/из Django как API
я не могу, поэтому, использовать традиционный метод Джанго иметь шаблон включает маркер CSRF, как этот <form action="." method="post">{% csrf_token %}
я могу сделать запрос на api-auth\login\
URL Django REST Рамочной основы , который вернет этот заголовок: Set-Cookie:csrftoken=tjQfRZXWW4GtnWfe5fhTYor7uWnAYqhz; expires=Mon, 01-Aug-2016 16:32:10 GMT; Max-Age=31449600; Path=/
- но я не могу извлечь этот файл cookie для отправки обратно с помощью моих запросов AJAX h 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'));
}
}
});
Как загрузки страницы я называю это, чтобы убедиться, у меня есть маркер:
$.ajax(loginUrl, { method: "OPTIONS", async: false })
.done(function(data, textStatus, jqXHR) {
console.log(jqXHR)
[email protected] = $.cookie("csrftoken")
console.log($.cookie("csrftoken"))
console.log(app.csrftoken)
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
});
Это не совсем чистый, но я не доказанный концепция для меня еще.
Что такое «правильный» способ аутентификации/защиты от CSRF, когда интерфейс и бэкэнд находятся на разных портах/доменах?
Я думаю, что у меня уже есть это покрытие - моя просьба не терпит неудачу по причинам CORS. Моя проблема, насколько я могу судить, заключается в том, что мой первый запрос (опция «ОПЦИИ») не устанавливает файл cookie 'csrftoken', поэтому я не могу его прочитать, чтобы добавить его в качестве заголовка, или он автоматически отправляется с последующим запрос. Выполнение запроса напрямую (не используя AJAX) правильно устанавливает cookie. Есть что-то, запрещающее настройку cookie? – jimbofreedman
Если это так, я могу подумать о двух других вещах, которые могут пойти не так: во-первых, убедитесь, что параметр 'crossDomain' запроса AJAX имеет значение« True », как описано в api.jquery.com/jQuery. Аякс. Также вероятно, что если вы не включаете тег шаблона CSRF на странице, которую вы просматриваете (например, страница не имеет формы), Django может не включать маркер в заголовке по умолчанию. Вы можете использовать 'decor_csrf_cookie (view)' decorator вокруг вашего представления, чтобы заставить это (см. Https://docs.djangoproject.com/en/dev/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie) – ilkahnate