在添加csrf令牌后POST AJAX DJANGO 403 forbbiden

时间:2015-05-18 18:45:36

标签: jquery ajax django angularjs post

我正在尝试向我的django的后端做一个ajax帖子,我得到了“错误403,forbbiden”,使用AngularJS作为前端。

我知道我必须通过我的帖子数据发送csrf令牌,但我的django视图没有检测到它。

我尝试过所有内容,因为在我的表单中使用了'{%csrf_token%}',{{csrf_token}}在我的ajax数据中,我仍然会遇到同样的错误。

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档案

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

两个console.log都打印相同的内容。但是,我的django观点没有回归。 我感谢所有的帮助。谢谢。

1 个答案:

答案 0 :(得分:0)

对于每个XHR请求,您将必须添加一个名为X-CSRFToken标头的标头以及CSRF标记的值。

请注意,默认情况下,启用CSRF保护后,Django 将始终在第一个GET请求中发送名为csrf的cookie (不需要csrf保护)。 因此,您不需要能够为您提供令牌的端点。

您必须阅读存储在csrf cookie中的令牌。您可以使用ngCookies访问cookie,获取令牌并将其添加到模块发出的每个请求中。 这就是我管理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;
    })

这足以用CSRF保护所有端点 在您的settings.py中:

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

顺便说一句,既然你已经运行了AngularJs,忘了用JQuery做你的请求。如果您计划构建RESTful API,请查看ngResource

jQuery方法: 如果您更喜欢使用jQuery而不是Angular,那么这篇文章将向您展示django 403 error on ajax view with csrf token

希望这会有所帮助