csrf middleware token from request body

233 views
Skip to first unread message

Richard Jeffries

unread,
Mar 13, 2015, 4:57:23 AM3/13/15
to django-d...@googlegroups.com

Hi,


Not sure if this breaks any RFC’s or there’s another valid reason why this doesn’t exist already but I’ve noticed that certain client frameworks (looking at you angular) have a tendency to put POST data in the request body.


For example, the following angular code


$http( {

method: 'POST’,

url: theurl

headers : {

'Content-Type': 'application/json;  charset=utf-8'

},

data: { 'csrfmiddlewaretoken': thetoken),

    ‘foo’ : bar}

};).


The csrfmiddlewaretoken then ends up in the request.body as a json string (regardless of the content-type) and not request.POST and the csrf middleware rejects the request. I’m not an angular expert but as far as I can tell if the data is not a simple string then it gets JSON’fied and ends up in the request body.

I was proposing adding the following to csry.py as a last chance saloon attempt to find the token


# Last chance, check the body for a JSON payload

if request_csrf_token == "":

    try:

        bodydict = json.loads(request.body)

        request_csrf_token = bodydict.get('csrfmiddlewaretoken', '')

    except:

        pass


I’ve created a fork and branch with this modification


https://github.com/rjjeffries/django.git - branch csrf_jsonbody


Thanks

Richard

Florian Apolloner

unread,
Mar 13, 2015, 11:14:55 AM3/13/15
to django-d...@googlegroups.com
I am pretty sure you can configure angular to send the token in the header. Either way, we are not going to try and load json, just we can't find a token otherwise…

Cheers,
Florian

Rafał Pitoń

unread,
Mar 13, 2015, 2:42:36 PM3/13/15
to django-d...@googlegroups.com
Pretty much, you have to tell Angular to use cookie for token and send CSRF header:

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

However I would argue that option to always send CSRF cookie would be useful in situations when your app templates contain no {% csrf_token %}, yet you need that cookie for API calls from frontend to sign their POST's to backend.

Richard Jeffries

unread,
Mar 14, 2015, 4:14:19 AM3/14/15
to django-d...@googlegroups.com
Hi,

Thats pretty much the use case I have (accessing an API with no template). I couldn't get angular to play nice even with the below settings so I'd resorted to POST-ing the token but then I encountered the POST dict being turned into JSON.

Appreciate that this short-coming is not django so will bow down to your superior knowledge in this area if you feel this too much of a 'hack'

Thanks
Richard

Thomas Rega

unread,
Mar 14, 2015, 7:09:21 AM3/14/15
to django-d...@googlegroups.com
Hi,

for me the following snippets work:

var testRun = angular.module('testRun', ['ui.bootstrap']);
testRun.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});

See: https://github.com/thoreg/test_executor/blob/master/test_executor/static/js/app.js

Good Luck
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-develop...@googlegroups.com.
> To post to this group, send email to django-d...@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/748a910f-e8c0-4c37-bcbb-d907baa00a8a%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Carl Meyer

unread,
Mar 14, 2015, 8:22:52 PM3/14/15
to django-d...@googlegroups.com
Hi Rafał,
That option exists and is documented:
https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#django.views.decorators.csrf.ensure_csrf_cookie

It's a view decorator, but if you look at its implementation, you can
see that it's based on a middleware, which would be easy to apply to a
whole site if that's what you wanted.

Carl

signature.asc
Reply all
Reply to author
Forward
0 new messages