我正在使用ajax请求发送POST但由于csrf_token而得到响应403。我只是使用Vuejs和后端使用Django来分割前端只是为了响应API所以我不能使用Django模板来渲染{%csrf_token%}或者在会话中使用csrftoken来使用getcookie('csrftoken'),就像在Django的doc中推荐的那样。有没有人像我一样面对这个问题并得到一些解决方案?谢谢你,如果你可以帮助我。
答案 0 :(得分:4)
您可以在AJAX请求的标头中设置CSRF令牌。例如,如果你使用jquery和jquery.cookie库,你可以像这样轻松检索Django-set csrftoken
cookie:
$.ajax({
url : 'YOUR_URL_HERE',
headers: {'X-CSRFToken': $.cookie('csrftoken')},
type: 'POST',
dataType: 'json',
data: {},
success: function() {
},
error: function(xhr, errMsg, err) {
},
});
Django文档还包括以下部分:https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax
请注意,此解决方案可能取决于您的特定Django设置。上面的Django文档链接非常清楚地详述了所有内容。
编辑:
鉴于即使您的初始页面请求不是由Django提供的,您也可以通过以下方式完成所需的工作......
1。)在Django应用程序中创建一个手动生成并返回CSRF令牌的视图(使用django.middleware.csrf.get_token
):
def get_csrf_token(request):
token = django.middleware.csrf.get_token(request)
return JsonResponse({'token': token})
2。)您还需要在Django URL文件中添加适当的条目:
url(r'^get-token/$', get_csrf_token)
3.)然后您的Vue.js应用程序可以使用此端点获取CSRF令牌。这不需要是用户发起的事件;例如,您可以将前端应用配置为在$(document).ready()
事件中获取它。然后,使用您首选的AJAX库(我在我的示例中使用jQuery):
$.ajax({
url: '/get-token/',
type: 'GET',
dataType: 'json',
success: function(data) {
$.cookie('csrftoken', data.token); // set the csrftoken cookie
}
});
4.。)现在您的csrftoken
cookie已设置,并且可用于后续POST请求。
$.ajax({
url : 'YOUR_URL_HERE',
headers: {'X-CSRFToken': $.cookie('csrftoken')},
type: 'POST',
dataType: 'json',
data: {},
success: function() {
},
error: function(xhr, errMsg, err) {
},
});
我已经使用jQuery实现了AJAX功能,使用了jQuery.cookie库来获取和设置cookie,但当然你可以使用你喜欢的任何库来实现这些功能。
答案 1 :(得分:1)
根据Django documentation,您只需在视图上使用ensure_csrf_cookie
装饰器,就会发送带有响应的令牌的Cookie。
答案 2 :(得分:-1)
这将是非常不受欢迎的,但是我发现这是一种相对简单,安全且不干扰用户的分离前端/后端的方法。
在VueJS应用中,当用户尝试访问页面且未经身份验证时,您可能会获得登录重定向。
因此,与其将其发送到vue路由器页面,不如将其重定向到/ account / login /(或某些django应用程序路由-将异常置于cloudfront中,或将/ account / login /的nginx代理置于代理传递给django) -然后在login.html模板中,只需将javascript window.location.href用于您的vueJS登录页面/ login
csrf_token将被设置为HttpOnly,安全的cookie(这是您想要的),并且对用户的干扰极小,甚至没有理由担心。