Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSRF headers not being set in AngularJS

I'm developing a DJANGO + AngularJS application, where the angular part is not being served by django.

I set the angular $httpProvider as follows:

myApp = angular.module('myApp', [])

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

Then, before doing any POST, I do a GET which sets the cookie. I can confirm through Chrome that the cookie is set:

set-cookie:csrftoken=hg88ZZFEdLPnwDdN1eiNquA8YzTySdQO; expires=Tue, 19-Aug-2014 12:26:35 GMT; Max-Age=31449600; Path=/

(it's visible in resources/cookies/localhost in the Chrome developer tools)

However when I do a POST, no X-CSRFToken header is being set

this is the POST as recorded by Chrome:

POST /data/activities/search HTTP/1.1
Host: localhost:14080
Connection: keep-alive
Content-Length: 2
Accept: application/json, text/plain, */*
Origin: http://localhost:14080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:14080/public/html/main.html?codekitCB=398694184.799418
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: csrftoken=hg88ZZFEdLPnwDdN1eiNquA8YzTySdQO

Why is no header being set? What else should I do to activate this functionality?

(side note: if I manually pass the header in the $http() call, the POST request works fine.. therefore the problem is really the header not being set by AngularJS)

like image 811
luca Avatar asked Aug 20 '13 12:08

luca


5 Answers

very simple answer: it's only available from version 1.2.0, which is at the moment a release candidate.

like image 162
luca Avatar answered Nov 03 '22 06:11

luca


The 1.2.0 update wasn't sufficient for me when using Safari or Firefox (Chrome was working just fine all the time). The problem with Safari and Firefox was that the Django backend didn't send the csrf-cookie in the HTTP response.

What I had to do was add the @ensure_csrf_cookie decorator to my view function that builds up the page for Angularjs.

@ensure_csrf_token
def my_view(request):
    ...

and in the javascript file:

myApp.config(function($httpProvider) {
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}

At least for now I have no idea why Chrome works without it but the other browsers don't.

like image 21
Janne Avatar answered Nov 03 '22 04:11

Janne


I had a similar issue and it was embarrassingly my fault.

My mistake:

$.post('/url', data)

Make sure you're using the $http object!

$http.post('/url', data)

It was very easy to make this mistake since both seem to work equally as well as each other, except former does not look at $http.defaults.headers.common['X-CSRFToken'], etc.

like image 44
gak Avatar answered Nov 03 '22 06:11

gak


app.config(["$httpProvider", function($httpProvider) {
    var csrfToken = getCookie('csrftoken');
    $httpProvider.defaults.headers.common['X-CSRFToken'] = csrfToken; 
}])

getCookie() take from https://docs.djangoproject.com/en/dev/ref/contrib/csrf/


Or set each method separately

 $httpProvider.defaults.headers.post['X-CS....
 $httpProvider.defaults.headers.get['X-CS....
like image 1
Serge K. Avatar answered Nov 03 '22 06:11

Serge K.


Angular changes very frequently and some answers do not work with latest versions. In any way, since Angular expects a XSRF-TOKEN cookie name, and sends a X-XSRF-TOKEN header, we can alternatively simply tell Django to use these by default:

CSRF_COOKIE_NAME = 'XSRF-TOKEN'
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN'

The first setting (see docs) is the cookie name for the csrf token, whereas the second one (see docs, only introduced in 1.9) is the respective header name.

Last, just for reference, do not forget to set:

CSRF_COOKIE_HTTPONLY = False
like image 1
Wtower Avatar answered Nov 03 '22 05:11

Wtower