Django csrf token + Angularjs



У меня есть django, работающий на сервере apache с помощью mod_wsgi, а также приложение angularjs, обслуживаемое непосредственно apache, а не django. Я хотел бы сделать почтовые вызовы на сервер django (работает rest_framework), но у меня возникли проблемы с токеном csrf.



есть ли способ установить токен с сервера, не ставя {% csrf token %} как часть шаблона (так как эти страницы не проходят через django)?




  1. Я хотел бы иметь возможность получить csrf токен через запрос GET в виде файла cookie.

  2. Я хотел бы иметь возможность делать запросы POST на сервер django со значением cookie токена csrf.

663   5  

5 ответов:

Django и AngularJS оба уже имеют поддержку CSRF, ваша часть довольно проста.

во-первых, вам нужно включить CSRF в Django, я считаю, что вы уже сделали это, если нет, следуйте Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax.

теперь Django установит куки с именем csrftoken на первый запрос GET и ожидает пользовательский заголовок HTTP X-CSRFToken на более поздних запросах POST/PUT/DELETE.

для углового, он ожидает Куки по имени XSRF-TOKEN и будет делать POST/PUT / DELETE запросы с X-XSRF-TOKEN заголовок, так что вам нужно сделать немного настройки, чтобы сделать два идут друг с другом:

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';

добавить выше двух строк где-то в вашем JS-коде, модуль.блок config () - хорошее место для этого.

вот именно.

Примечание: это для углового 1.1.5, более старые версии, возможно, потребуется другой подход.

обновление:

так как угловой приложение не подается по django, для того, чтобы файл cookie был установлен, angular app должен сначала сделать запрос GET на django.

var foo = angular.module('foo', ['bar']);

foo.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);

и все модули сервисов и контроллеров, где используется $http, будут отправлять запросы с токеном csrf.

после поиска вокруг, что работало для меня было от этот пост следующий код:

angular.module( '[your module name]',
    ... [some dependencies] ...
    'ngCookies',
    ... [other dependencies] ...
)
.run( function run( $http, $cookies ){

    // For CSRF token compatibility with Django
    $http.defaults.headers.post['X-CSRFToken'] = $cookies.get('csrftoken');
})

Это, конечно, после получения файла cookie через запрос GET от сервера django.

Я также изучил некоторые другие ответы здесь, включая Ye Liun, но не смог найти ничего в официальных документах, указывающих изменения параметров по умолчанию для xsrf на $httpProvider, кроме это тянуть запрос который не работал для меня на момент написания этого поста.

Я создал приложение Django для моего приложения AngularJS, в том же проекте Django, что и мое приложение (REST) API Django, которое служит только индексу.html-файл (который является просто sym.соединение.) Таким образом, файл Cookie CSRF устанавливается без дополнительного запроса GET.

пожалуйста, смотрите мой ответ здесь о одностраничное веб-приложение AngularJS на поддомене a разговаривает с API Django JSON (REST) на поддомене B с использованием защиты CORS и CSRF

Если у вас есть куки, настроенные на запрещение доступа к javascript, вам нужно сделать следующее. В вашем шаблоне перед созданием приложения django добавьте следующее:

<script>
    window.csrf_token = "{{ csrf_token }}";
</script>

в вашем угловом приложении добавьте это:

angularApp.config(["$httpProvider", function($httpProvider) {
    $httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
}]);

по крайней мере, через Django 1.9, токен CSRF не изменяется с каждым запросом. Меняется только при входе пользователя в систему. Если вы делаете одностраничное угловое приложение, вам нужно убедиться, что вы сбросили токен при входе/выходе из системы, и это должно работать штраф.

Примечание: В настоящее время это не работает в Django 1.10 или более поздней версии из-за изменения токена CSRF при каждом запросе. Смотрите передайте токен Django CSRF в Angular с помощью CSRF_COOKIE_HTTPONLY

Comments

    Ничего не найдено.