【问题标题】:POST AJAX DJANGO 403 forbbiden after adding csrf token添加 csrf 令牌后禁止发布 AJAX DJANGO 403
【发布时间】:2015-07-30 09:37:04
【问题描述】:

我正在尝试将 ajax 发布到我的 django 的后端,我收到“错误 403,禁止”,使用 AngularJS 作为前端。

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

我已经尝试了所有方法,因为在我的表单中使用了“{%csrf_token%}”,在我的 ajax 数据中使用了 {{csrf_token}},但我仍然遇到同样的错误。

查看.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(配置)

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 视图没有返回。 我感谢所有的帮助。谢谢。

【问题讨论】:

  • 您确定没有看到任何控制台日志错误吗?
  • @karthikr 是的,我检查了 chrome 上的 console.log 并在表单数据中显示:valor:'something', csrfmiddlewaretoken:'Qgdxhxh243 ...'。这就是为什么我不明白为什么 Django 返回 403。我错过了什么?

标签: jquery ajax django angularjs post


【解决方案1】:

对于您将发出的每个 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

希望对你有帮助

【讨论】:

  • 哦......它没有工作:(谢谢你顺便说一句。我仍然得到 403 Forbbiden
  • 您能否提供用于发出请求的代码。我猜在你的角度控制器中。您应该尝试使用 chrome 应用程序 Postman 发送请求
  • 好的,在这种情况下,这里不需要 Angular。如果您使用 jQuery 进行请求,则不需要 Angular。我已将 jQuery 方法添加到我的答案中,效果很好
  • 试过了,还是不行,getCookie()返回null。我只使用 django.middleware.csrf.get_token(request) 得到了一个令牌,但仍然得到 403
  • 你可能会尝试删除cookies,这可能会导致问题。
猜你喜欢
  • 2016-05-08
  • 2012-10-13
  • 2021-11-04
  • 2015-10-15
  • 1970-01-01
  • 2018-11-06
  • 2013-08-24
  • 2021-07-08
  • 2020-10-12
相关资源
最近更新 更多