【问题标题】:flask CSRF and fetch API烧瓶 CSRF 和 fetch API
【发布时间】:2020-02-10 15:21:23
【问题描述】:

根据 Flask-WTF 文档

这是使用 AJAX 时如何传递 CSRF Token

<script type="text/javascript">
    var csrf_token = "{{ csrf_token() }}";

    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrf_token);
            }
        }
    });
</script>

有没有办法在使用 fetch API 时实现 CSRF 保护?

还尝试添加credentials: 'include',

*编辑 我收到 2 个错误:

the CSRF token is missing 
The CSRF session token is missing

这是我的代码

  let csrf_token = "{{ csrf_token() }}";
 let payload = {
        // some data
        "csrf_token": csrf_token
      }

let header = {   'content-type': 'application/json','accept': 'application/json',"X-CSRFToken": csrf_token}
paypal.Buttons({

    createOrder: function(data, actions) {
                return fetch(prefix.concat("/payment/paypalCreate"), {
                  method: "POST",
                  headers: header ,
                  body:JSON.stringify(payload),
                  credentials: 'include',
                  })
                    .then(function(res) {
                        return res.json();
                    }).then(function(data) {
                      console.log(typeof(data))
                        return data.id
                    })
                .catch(err => {
                  console.log(err);
                });
        }

【问题讨论】:

标签: python flask csrf flask-wtforms


【解决方案1】:

我知道这是个老问题,但如果需要它可能会有所帮助。

from flask_wtf.csrf import CSRFProtect
#depending on how you define app 
#either 
CSRFProtect(app) 
#or 
csrf = CSRFProtect()
csrf.init_app(app)

并在表单元素中添加onsubmit="fetchSumbitWtf(event)",获取函数将是

function fetchSumbitWtf(e) {
    e.preventDefault();
    data = {"first": "first", "second": "second"}
    var url = "/some/";
    console.log(e.target.csrf_token.value)
    fetch(url, {
        method: 'POST', 
        headers: {
          'Content-Type': 'application/json',
          'X-CSRF-TOKEN': e.target.csrf_token.value
        },
        body: JSON.stringify(data),
        credentials: 'same-origin'
      })
      .then(response => response.json())
        .then(data => {
            console.log(data)
        })
        .catch((error) => {
            console.log("error happened")
        });
}

flask 视图功能可以是

@app.route("/some/", methods=["POST"])
def fetch_form():
    form = SomeFlaskForm()
    if form.validate_on_submit():
        print("validated")
        return jsonify({"Success": True}), 200

【讨论】:

    【解决方案2】:

    我找到了解决这个问题的方法,但我不知道是否有人需要它,但是... 我刚刚将 csrf 令牌传递给了 javascript 函数 这是我的javascript。

    function deleteUser(userId, csrf) {
      fetch('/admin/deleteUser', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': csrf
          },
          body: JSON.stringify({
            userId: userId
          })
        }).then(response => response.json())
        .then(data => {
          console.log('Success:', data);
          window.location.href = data
        })
    }
    然后在我将 csrf 令牌传递给函数的模板中
    <button onclick="deleteUser({{ User.id }}, '{{ csrf_token() }}')">
    
     from flask_wtf.csrf import CSRFProtect
        #depending on how you define app 
        #either 
        CSRFProtect(app) 
        #or 
        csrf = CSRFProtect()
        csrf.init_app(app)
    

    【讨论】:

      猜你喜欢
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 2021-09-04
      相关资源
      最近更新 更多