我正在尝试向我的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观点没有回归。 我感谢所有的帮助。谢谢。
答案 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
希望这会有所帮助