5

I'm trying to use Django-Angular to make a AJAX call to a view in Django. I'm following this guide here.

However, when I make a POST I'm getting the message: CSRF verification failed. Request aborted. It seems like the action as described in the docs process_something isn't being called as I shouldn't need the token.

Can anyone spot the issue, below is what I have tried so far...

Here is the relevant js controller script:

   var in_data = {action: 'process_something', somevar: $scope.somevar};
   var post_call = CbgenRestangularDjango.all('pin-verification/').post(in_data)

and the form:

<form ng-controller="PinValidationFormCtrl"  name="CompanyValidPinForm" class="bs-callout">
        <div class="col-xs-2">
            <input class="form-control" name="somevar" ng-model="somevar" type="text">
        </div>

        <div class="col-xs-2">
            <button type="button" class="btn btn-default" ng-click="submitPin()">Verify Pin</button>
        </div>
</form>

and the view:

class VerificationView(JSONResponseMixin, View):
    # other view methods

    @allowed_action
    def process_something(self, in_data):
        # process input data
        out_data = {
            'foo': 'bar',
            'success': True,
        }
        return out_data
GrantU
  • 6,325
  • 16
  • 59
  • 89
  • 2
    @Stewie I think the question is clear, and you can see what I have already tried. I'm unsure why you posted your comment, please elaborate. Thanks. – GrantU Dec 29 '13 at 18:46
  • Have you setup angular app as specified [here](http://django-angular.readthedocs.org/en/latest/csrf-protection.html)? – mariodev Dec 29 '13 at 19:12
  • yep @mariodev I have :). I have Django-Angular working for normal GET requests, but for some reason it's not calling process_something function in the view on POSTs being made, and I think this is why I have the message about CSRF as [@]allowed_action is not being run. – GrantU Dec 29 '13 at 21:32
  • Does the POST request work when you decorate `process_something` method with `@csrf_exempt`? (If decorating class-based view's method with `csrf_exempt` doesn't [work](https://code.djangoproject.com/ticket/15794), try [this](http://stackoverflow.com/a/10252521/1432478)) – vucalur Jan 02 '14 at 16:16
  • a (firebug) screenshot of the attempted post request would also be helpful. – angabriel Jan 06 '14 at 16:56

4 Answers4

5

The post() method accepts a config parameter to pass the X_CSRFTOKEN header:

var config = { headers : { 'X_CSRFTOKEN' : $cookies.csrf_token }};
var in_data = {action: 'process_something', somevar: $scope.somevar};
var post_call = 
CbgenRestangularDjango.all('pin-verification/').post(in_data, config);

In your view's template the form must include the token as follows:

<form ...>
    {% csrf_token %}
    ...
</form>

Note $cookies depends on ngCookies (see http://docs.angularjs.org/api/ngCookies.$cookies)

mariodev
  • 13,928
  • 3
  • 49
  • 61
miraculixx
  • 10,034
  • 2
  • 41
  • 60
4

You must pass the csrf token when sending a HTTP POST request.

Include {% csrf_token %} in your form or add a custom header X-CSRFToken. This should work.

mariodev
  • 13,928
  • 3
  • 49
  • 61
ghopst
  • 166
  • 3
3

Its most likely you are missing a header in your angular's app module config.

Try setting the following

.config(function($httpProvider) {
  $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

Django applications do not require this header, but if it is missing, all invocations to: request.is_ajax() would return False, even for perfectly valid Ajax requests

Found here: http://django-angular.readthedocs.org/en/latest/integration.html Also there was an api change at angular version >= 1.1.x (this header default was dropped since that version). Perhaps Django did not catch up with their documentation in every part.


Maybe you just need to clear your browser cache as you might have an outdated cookie sending an invalid token letting the request mapping fail.

angabriel
  • 4,979
  • 2
  • 35
  • 37
  • Did you try this? I deleted this answer for some days but I am still curious if this can be the problem so I reactivated it. – angabriel Jan 07 '14 at 09:30
2

you can also try/use the @csrf_exempt decorator

--> https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.csrf_exempt

and here's the Django documentation of how to apply it to class based views =)

https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-class-based-views

David Lam
  • 4,689
  • 3
  • 23
  • 34