简体   繁体   中英

POST AJAX DJANGO 403 forbbiden after adding csrf token

I am trying to do an ajax post to my django's backend and I am getting "error 403, forbbiden", using AngularJS as front-end.

I know that I have to send through my post data the csrf token, but my django view is not detecting it.

I had tried everything, since using the '{%csrf_token%}' in my forms, {{csrf_token}} in my ajax data and I still get the same error.

View.py

from django.views.decorators.csrf import *

def getCookie(request):
   if request.method == 'GET':
       data = django.middleware.csrf.get_token(request)
       return JsonResponse(data, safe=False)

@csrf_protect
def guardarGrupo(request):
   var = request.POST.get('csrfmiddlewaretoken', '')
     if request.is_ajax() and request.method=='POST':    
      return HttpResponse(var)

`

urls.py

urlpatterns = patterns('',
  url(r'^grupo/guardarGrupo/$', views.guardarGrupo, name='GuardarGrupo'),
  url(r'^getCookie/$', views.getCookie, name='getCookie'),  
  ...

settings.py

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
...

JS file

 var token;
    $.getJSON('http://127.0.0.1:8000/getCookie/', function(json) {
        console.log("getjson:"+json);
        token = json;
    }).done(function() {
        console.log("token:"+token );
        $.ajax({
            type: 'POST',
            url: 'http://127.0.0.1:8000/grupo/guardarGrupo/',
            data: {valor: 'hola',csrfmiddlewaretoken : token},
            success: function(data) { alert('data: ' + data); },
            error: function (error) { alert(token);},
        });

    });

angularjs (config)

function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
angular.module('dService', [])
.config(['$httpProvider', function($httpProvider, $http) {
        $httpProvider.defaults.useXDomain = true;
        $httpProvider.defaults.withCredentials = true;
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    }
]);

Both console.log prints the same. But, my django view isn't returning. I appreciate all the help. Thank you.

For each XHR requests you'll make you'll have to add a header called X-CSRFToken header with the value of the CSRF token.

Note that by default, with the CSRF protection on, Django will always send the cookie called csrf on the first GET request (no csrf protection required). So you don't need an endpoint that will give you the token.

You have to read the token which is stored in the csrf cookie. You can use ngCookies to access the cookie, grab the token and add it to each request made by your module. This is how I manage the CSRF :

'use strict';

angular.module('mymodule', [
    'ngCookies',
    //...
    ])
    .config(['$httpProvider', function($httpProvider){
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    }])
    .run(function($http, $cookies) {
        $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
    })

This will be enough to protect all your endpoints with CSRF in your settings.py:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
)

Btw, now that you have AngularJs running forget about doing your requests with JQuery. Have a look at ngResource if your planning on building a RESTful API.

The jQuery Method : If you prefer using jQuery rather than Angular, this post will show you to do it django 403 error on ajax view with csrf token

hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM