Django的csrf标记+ Angularjs
我有一个使用mod_wsgi的apache服务器上运行的django,以及由apache直接提供的angularjs应用程序,而不是由django运行。 我想进行POST调用Django服务器(运行rest_framework),但我有问题与csrf令牌。
有没有把{% csrf token %}
作为模板的一部分来设置从服务器的{% csrf token %}
(因为这些页面没有经过Django)?
- 我希望能够通过GET请求获取csrf令牌作为cookie。
- 我希望能够使用csrf标记cookie值向django服务器发出POST请求。
Django和AngularJS都已经拥有CSRF支持,你的部分很简单。
首先,您需要在Django中启用CSRF,我相信您已经这么做了,如果没有,请按照Django文档https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax 。
现在,Django将在第一个GET请求中设置一个名为csrftoken
的cookie,并在稍后的POST / PUT / DELETE请求中期待一个自定义的HTTP头X-CSRFToken
。
对于Angular来说,它期望名为XSRF-TOKEN
的cookie,并且将使用X-XSRF-TOKEN
标题执行POST / PUT / DELETE请求,所以您需要做一些调整以使两者一致:
$httpProvider.defaults.xsrfCookieName = 'csrftoken'; $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
在你的js代码的某处添加上面两行,module.config()块是一个很好的地方。
而已。
注:这是为angular1.1.5,旧版本可能需要不同的方法。
更新:
由于angular色应用程序不是由Django提供的,为了让cookie被设置,angular度应用程序需要首先对django进行GET请求。
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'); })
这当然是通过从Django服务器获取GET请求获取cookie后。
我也看了一些其他的答案,包括Ye Liun的,但在官方文档中找不到任何东西,在$ httpProvider中指定xsrf的默认选项的更改,除了这个pull请求在我的我写这篇文章的时间。
我为我的AngularJS应用程序创build了一个Django应用程序,与我的(REST)API Django应用程序在同一个Django项目中,只提供index.html文件(这只是一个sym.link)。 通过这种方式,CSRF Cookie不需要额外的GET请求。
请在这里看到我的答案关于子域A上的AngularJS单页Web应用程序使用CORS和CSRF保护与子域B上的Django JSON(REST)API交谈
如果您的Cookie设置为禁止JavaScript访问,则需要执行以下操作。 在您的模板中,在创builddjango应用程序之前,添加以下内容:
<script> window.csrf_token = "{{ csrf_token }}"; </script>
在你的angular度的应用程序,添加这个:
angularApp.config(["$httpProvider", function($httpProvider) { $httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token; }]);
至less通过Django 1.9,CSRF令牌不会随着每个请求而改变。 它只会在用户login时改变。如果你正在做一个页面angular度的应用程序,你需要确保你重置login/注销令牌,这应该工作正常。
注:由于CSRF令牌在每个请求上发生更改,因此目前在Django 1.10或更高版本中不起作用。 请参阅通过CSRF_COOKIE_HTTPONLY将Django CSRF令牌传递给Angular