欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

django框架下用ajax发送post请求403forbidden解决方法

程序员文章站 2022-05-29 21:27:41
...

方法来自【Python建站】12.用户验证登录官方文档,这里对方法进行总结方便参考和日后复习
环境:Django2.1+VueJS
插件:前端:reqwest 后端:Django REST framework
适用于使用

问题引入

在网站中加入登录验证模块时,使用ajax向后端提交数据
前端发送请求模块:

userLogin:function(){
     var self = this
     reqwest({
         url:'/api/index',
         method:'post',
         type:'json',
         data:{
             username: self.username,
             password: self.password,
         },
          //获取验证结果
         success:function(data){
             console.log(data)
         },
         //打印错误信息
         error:function(error){
             console.log(error)
         }
         
     })
 },

后端验证模块:(去除了一些与本文无关内容)

@api_view(['GET', 'POST'])
def indexData(request):
# 验证用户密码是否正确
if request.method == 'POST':
    # print('ok')

    # post来的信息
    username = request.POST['username']
    password = request.POST['password']
    # 是否通过了User login的验证
    user = authenticate(username=username, password=password)
    print(user)  # 正确返回user 错误返回none
    if user != None: 
        login(request, user)
        return Response({'loginType': 'ok'})

目的是在使用后端验证后,向前端返回验证{‘loginType’: ‘ok’}的结果,但在提交post请求后出现了问题,POST请求返回了403 Forbidden的Status Code

status: 403
statusText: "Forbidden

同时后端打印出了这样的错误,说明POST请求被拒绝了

Forbidden: /api/index
[27/May/2019 12:21:04] "POST /api/index HTTP/1.1" 403 58

问题来源:Django中的CSRF防御机制阻止了前端POST请求提交,CSRF原理及应用参考Django中CSRF原理及应用详解

解决方法

通过对CSRF原理的了解,我们知道csrf验证其实是对http请求中一段随机字符串的验证用来防止CSRF攻击,所以我们需要在前端发送POST请求时携带这串随机字符通过Django的验证。在查询官方文档后发现在input标签前使用{% csrf_token %}就可以获得token通过Django的验证,但在这里我们使用了Vuejs来接管前端,Django的解决方法在这里并不生效。

由于我们是使用Vuejs来发送POST请求,所以我们需要在VueJS发送请求的模块下加入有CSRF的token的头部信息,在发送请求的模块中加入:

 headers:{
     "X-CSRFTOKEN":csrftoken
 },

那么这个csrftoken又要怎么获得呢?在这里使用了js-cookie,下载js文件放入项目的js文件夹。
在html的头部加入

<script src="{% static 'js/js.cookie.js' %}" charset="utf-8"></script>

同时在body的最后加入

 <script type="text/javascript">
     var csrftoken = Cookies.get('csrftoken')
     console.log(csrftoken)
 </script>

现在保存,打印一下csrftoken,可以看到这样的一串随机字符,这就是csrf的token

BE7lgnhQ2giehLcTH9ydBotsxQhQKOIg32bdnczb8LvUjCWpGW3ndCnYnu30xmMl

现在再点击登录,可以发现不会被CSRF拦截了,成功打印出{loginType: “ok”}的信息

相关标签: Django 403