Django的csrf标记+ Angularjs

我有一个使用mod_wsgi的apache服务器上运行的django,以及由apache直接提供的angularjs应用程序,而不是由django运行。 我想进行POST调用Django服务器(运行rest_framework),但我有问题与csrf令牌。

有没有把{% csrf token %}作为模板的一部分来设置从服务器的{% csrf token %} (因为这些页面没有经过Django)?

  1. 我希望能够通过GET请求获取csrf令牌作为cookie。
  2. 我希望能够使用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 Coo​​kie不需要额外的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