Django csrf token + Angularjs
У меня есть django, работающий на сервере apache с помощью mod_wsgi, а также приложение angularjs, обслуживаемое непосредственно apache, а не django. Я хотел бы сделать почтовые вызовы на сервер django (работает rest_framework), но у меня возникли проблемы с токеном csrf.
есть ли способ установить токен с сервера, не ставя {% csrf token %} как часть шаблона (так как эти страницы не проходят через django)?
- Я хотел бы иметь возможность получить csrf токен через запрос GET в виде файла cookie.
- Я хотел бы иметь возможность делать запросы POST на сервер django со значением cookie токена csrf.
5 ответов:
Django и AngularJS оба уже имеют поддержку CSRF, ваша часть довольно проста.
во-первых, вам нужно включить CSRF в Django, я считаю, что вы уже сделали это, если нет, следуйте Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax.
теперь Django установит куки с именем
csrftokenна первый запрос GET и ожидает пользовательский заголовок HTTPX-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