zoukankan      html  css  js  c++  java
  • 六十六:CSRF攻击与防御之CSRF防御之ajax防御和ajax封装

    app里面还是要绑定CSRFProtect

    from flask_wtf import CSRFProtect # flask_wtf 已经提供CSRF的防御手段
    CSRFProtect(app) # 绑定app

    登录页的js

    $(function () {
    $('#submit').click(function (event) {
    event.preventDefault(); // 阻止默认form提交表单行为
    var email = $('input[name=email]').val();
    var password = $('input[name=password]').val();
    var csrf_token = $('input[name=csrf_token]').val();
    // ajax
    $.post({
    'url': '/login/',
    'data': {
    'email': email,
    'password': password,
    'csrf_token': csrf_token
    },
    'success': function (data) {
    console.log(data)
    },
    'fail': function (error) {
    console.log(error)
    }
    });
    });
    });

    在页面里面引入js

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>登录</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="{{url_for('static', filename='login.js')}}"></script>
    </head>
    <body>
    <form action="" method="post">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
    <table>
    <tbody>
    <tr>
    <td>邮箱:</td>
    <td><input type="text" name="email"></td>
    </tr>
    <tr>
    <td>密码:</td>
    <td><input type="text" name="password"></td>
    </tr>
    <tr>
    <td></td>
    <td><input id="submit" type="submit" value="点击登录"></td>
    </tr>
    </tbody>
    </table>
    </form>
    </body>
    </html>

    请求页面

    以上方法虽能使用csrf_token防御,可需要在每一个提交页面都写,flask推荐的方式是将csrf_token()放到meta标签下下,发送数据时,放到头部信息中

    使用jinja的模板继承功能,base模板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="csrf_token" content="{{ csrf_token() }}">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    {% block head %}{% endblock %}
    </head>
    <body>
    <nav>导航条</nav>
    {% block body %}{% endblock %}
    <footer>底部</footer>
    </body>
    </html>

    登录页继承base模板

    {% extends 'base.html' %}

    {% block head %}
    <script src="{{url_for('static', filename='login.js')}}"></script>
    {% endblock %}

    {% block body %}
    <form action="" method="post">
    <table>
    <tbody>
    <tr>
    <td>邮箱:</td>
    <td><input type="text" name="email"></td>
    </tr>
    <tr>
    <td>密码:</td>
    <td><input type="text" name="password"></td>
    </tr>
    <tr>
    <td></td>
    <td><input id="submit" type="submit" value="点击登录"></td>
    </tr>
    </tbody>
    </table>
    </form>
    {% endblock %}

    登录页的js,将csrf放到头部信息

    $(function () {
    $('#submit').click(function (event) {
    event.preventDefault(); // 阻止默认form提交表单行为
    var email = $('input[name=email]').val();
    var password = $('input[name=password]').val();
    var csrf_token = $('meta[name=csrf_token]').attr('content');

    //设置头部信息
    $.ajaxSetup({
    'beforeSend': function (xhr, settings) {
    if(!/^(GET|HEAD|OPTIPNS|TRACE)$/i.test(settings.type) && !this.crossDomain){
    xhr.setRequestHeader('X-CSRFToken', csrf_token)
    }
    }
    });

    // ajax
    $.post({
    'url': '/login/',
    'data': {
    'email': email,
    'password': password,
    },
    'success': function (data) {
    console.log(data)
    },
    'fail': function (error) {
    console.log(error)
    }
    });
    });
    });

    访问

    由于每个js请求都需要在头部信息里面添加此参数,所以可以将添加头部信息拿出来封装

    封装一个统一的ajax,每次自动获取csrftoken并加到头部信息中

    var http = {
    'get':function (args) {
    args['method'] = 'get';
    this.ajax(args);
    },
    'post':function (args) {
    args['method'] = 'post';
    this.ajax(args);
    },
    'ajax':function (args) { // 将头部信息放到请求
    this._ajaxSetup();
    $.ajax(args);
    },
    '_ajaxSetup':function(){ // 将csrftoken放到头部信息
    $.ajaxSetup({
    'beforeSend': function (xhr, settings) {
    if(!/^(GET|HEAD|OPTIPNS|TRACE)$/i.test(settings.type) && !this.crossDomain){
    var csrf_token = $('meta[name=csrf_token]').attr('content'); // 获取csrf_token
    xhr.setRequestHeader('X-CSRFToken', csrf_token)
    }
    }
    });
    }
    };

    登录页的js,使用自定义的ajax机制

    $(function () {
    $('#submit').click(function (event) {
    event.preventDefault(); // 阻止默认form提交表单行为
    var email = $('input[name=email]').val();
    var password = $('input[name=password]').val();

    // 使用自定义的ajax
    http.post({
    'url': '/login/',
    'data': {
    'email': email,
    'password': password,
    },
    'success': function (data) {
    console.log(data)
    },
    'fail': function (error) {
    console.log(error)
    }
    });
    });
    });

    base模板中导入ajax的js

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="csrf_token" content="{{ csrf_token() }}">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="{{ url_for('static', filename='send_http.js') }}"></script>
    {% block head %}{% endblock %}
    </head>
    <body>
    <nav>导航条</nav>
    {% block body %}{% endblock %}
    <footer>底部</footer>
    </body>
    </html>

    请求

    这样发送请求的时候使用自己封装的ajax就可以实现每次发送请求的时候自动在头部信息加上csrftoken信息

  • 相关阅读:
    image
    MySQLdb
    【基础】Equal方法、面向对象-多态-继承-封装
    【转】SSL协议、SET协议、HTTPS简介
    【转】UML图与软件开发过程那点关系
    【转载】日本社会为啥没有“王思聪”
    调用0A中断输入字符串数据段的DUP定义
    字符串输入逆序输出(回车换行符)
    输入单个字符并输出
    仿射密码加密解密文件流
  • 原文地址:https://www.cnblogs.com/zhongyehai/p/11872832.html
Copyright © 2011-2022 走看看