Django csrf + Angularjs Icon

I have django running on an apache server using mod_wsgi, as well as an angularjs application that runs directly on apache, not django. I would like to make POST calls to the django server (rest_framework works), but I am having problems with the csrf token.

Is it possible to set a token from the server without putting {% csrf token %} as part of the template (since these pages do not go through django)?

  • I would like to be able to get the csrf token through a GET request as a cookie.
  • I would like to be able to then send POST requests to the django server using the cookie value of the csrf token.
+58
javascript python angularjs django
Aug 09 '13 at 22:13
source share
5 answers

Django and AngularJS already have CSRF support, your part is pretty simple.

First, you need to enable CSRF in Django, I suppose you've already done this, if not, follow the Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax .

Now Django will set a cookie named csrftoken in the first GET request and expect a custom X-CSRFToken HTTP header in subsequent POST / PUT / DELETE requests.

For Angular, it expects a cookie called XSRF-TOKEN and will make POST / PUT / DELETE requests with the X-XSRF-TOKEN , so you need to adjust it a bit so that both of them are with each other:

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

Add the above two lines somewhere in your js code, the module.config () block is a good place to do this.

What is it.

NOTE. This is for angular 1.1.5, older versions may require a different approach.

Update:

Since the angular application is not served by django in order to allow the cookie to be set, the angular application must first execute a GET request for django.

+102
Aug 09 '13 at 22:45
source share
 var foo = angular.module('foo', ['bar']); foo.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.xsrfCookieName = 'csrftoken'; $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken'; }]); 

And all modules and controllers that use $ http will send requests using the csrf token.

+56
Oct 20 '13 at 8:39
source share

After searching what worked for me, there was this post with the following code:

 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'); }) 

This, of course, after receiving the cookie through a GET request from the django server.

I also looked at some other answers here, including E. Leung, but could not find anything in the official docs defining the default parameter changes for xsrf to $ httpProvider, except for this pull request , which didn't work for me while writing this messages.

+11
Aug 10 '13 at 6:24
source share

I created a Django application for my AngularJS application, in the same Django project as the Django application for my (REST) ​​API, which only serves the index.html file (which is only sym.link). Thus, the CSRF Cookie is set without an additional GET request.

Please see my answer here AngularJS Single Web Application on a subdomain. Conversation with the Jango JSON API (REST) ​​in subdomain B using CORS and CSRF security.

+1
Mar 22 '14 at 22:44
source share

If you have cookies that prohibit access to javascript, you need to do the following. In your template, before creating a django application, add the following:

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

In your angular app, add the following:

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

At least through Django 1.9, the CSRF token does not change with every request. It changes only when a user logs in. If you are using a single-page angular application, you need to make sure that you reset the token on login / logout, and this should work fine.

NOTE. This does not work in Django 1.10 or later due to a change in the CSRF token for each request. See Skip CSRF token for Django to angular using CSRF_COOKIE_HTTPONLY

0
May 27 '16 at 18:09
source share



All Articles