zoukankan      html  css  js  c++  java
  • pos提交提交数据时碰到Django csrf

      我的github(PS:希望star):https://github.com/thWinterSun/v-admin

      最近在用Vue写前端代码,再用vue-resource向后台提交数据。项目后台是用python+Django开发的。下面我就复盘一下我出现问题的经过。

      首先,想用vue进行数据交互只能引入vue-resource。

    <script src="js/vue.js"></script>
    <script src="js/vue-resource.js" ></script>

      之后我使用vm.$http方法向后台发送数据,其实和jquery的AJAX方法差不多,需要定义发送的地址、请求类型和发送数据等。

    this.$http({
        url:'/data/',
        data:JSON.stringify(Strdata),
        method:'POST'
    }).then(function(res){
        alert(res.data);                    
    });

    由于POST请求需要修改发送date的Content-Type为application/json,所以要设置emulateJSON为true,就变成这样了

    this.$http({
        url:'/data/',
        data:JSON.stringify(Strdata),
        method:'POST',
        emulateJSON:true
    }).then(function(res){
        alert(res.data);                    
    });

    正常来说这样就OK了,就可以拿到后台数据了。之后打开控制台,查看network,找到发出的data,看到HTTP状态码为302。

    怎么会被重定向到了登录页面,难道是登录超时??

    然后我看了看后台服务.....

    不应该是登录的问题啊,后面有请求成功返回啊,于是我对比了一下成功的请求和失败请求的HTTP请求头,发现好像是少了一个叫X-CSRFToken的东西。这是什么东西呢,于是我就google了一下,得到如下答案:

    Django 提供的 CSRF 防护机制

    django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,

    这样就能避免被 CSRF 攻击。

    1. 在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token
    2. 在所有的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 tag, django 就会自动帮你生成,见下面)
    3. 在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
    4. 在所有 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值。

     也就是说我每次向后台发送POST请求的时候,Django为了防止跨站请求伪造,即csrf攻击,提供了CsrfViewMiddleware中间件来防御csrf攻击。这时我就知道为什么之前将请求方式改为GET后成功了。

    之后就想办法在HTTP请求头中设置X-CSRFToken了,我查了很多资料,看到最多的一种方法是这样:

    <meta id="token" name="token" value="{ csrf_token() }">
    Vue.http.headers.common['X-CSRFToken'] = document.querySelector('#token').getAttribute('value');

    但是我试过还是重定向到登录页,不知道为什么。之后想了想,实际就是获取cookie里面的csrftoken值,然后在赋值给HTTP请求头里面的X-CSRFToken就行了。

    function getCookie(name) {
        var cookieValue = null;
         if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
            }
        }
        }
        return cookieValue;
    }
    
    Vue.http.headers.common['X-CSRFToken'] = getCookie('csrftoken');            

    之后HTTP请求头上的X-CSRFToken就有值了,响应也就成功了。

     

  • 相关阅读:
    UI 常用方法总结之--- UITableView
    UITextFiled 通知监听
    ios 本地通知
    AFNetworking 请求头的设置
    UI总结
    gitlab-server环境搭建
    redis 配置文件示例
    搭建spark集群
    kafka集群安装
    zookeeper集群搭建
  • 原文地址:https://www.cnblogs.com/daijinxue/p/7285379.html
Copyright © 2011-2022 走看看