【问题标题】:CSRF protection with a React Form, a Flask server, and Flask-WTF使用 React Form、Flask 服务器和 Flask-WTF 保护 CSRF
【发布时间】:2017-08-17 18:06:32
【问题描述】:

TL;DR 我需要保护我的表单免受 CSRF 攻击,我想将 ReactJS 用于前端,将 Flask/Flask-WTF 用于后端。

我正在重构一个使用 Python、Flask 和 Flask-WTF 构建的表单的网站,我想通过 PyPugjs 将 React 用于前端,而不是 Jinja2。我正在使用 Flask-WTF 来渲染表单,它负责处理 CSRF 令牌等。我知道如何使用 React 制作表单,但如何获得 CSRF 保护?

现在我的表单渲染看起来像这样:(使用 Pug)

mixin render_form(form, id='', action='Submit')
    form(method='POST', action='', id=id)
        =form.csrf_token

        each field in form
            fieldset
                if field.errors
                    each error in field.errors
                        .notification.error
                            #{error}

                #{field(placeholder=field.label.text)}

        button(type='submit') #{action}

【问题讨论】:

  • 问题应该是“如何使用 React + Python 添加输入字段”。 CSRF 保护只是一个提供随机值的字段,然后由服务器验证。

标签: javascript reactjs flask-wtforms csrf-protection


【解决方案1】:

当您发布表单时,您需要将 csrf 令牌作为标题 X-CSRFToken 发送。在此处查看他们的文档:http://flask-wtf.readthedocs.io/en/stable/csrf.html#javascript-requests

他们通过 jQuery 进行 POST 的示例在发送任何 POST/PUT/DELETE ajax 请求之前设置了X-CSRFToken

<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>

根据您用于将表单 POST 发送回服务器的库,设置标头 X-CSRFToken 的实现会有所不同。

【讨论】:

  • 这很有趣,但我需要知道如何用 React 来实现它。你能帮我解决这个问题吗?
  • 另外,我不想使用 Jinja 嵌入 CSRF 令牌。没有更好的方法吗? @kavun
  • @Hum4n01d 渲染一个 CSRF 令牌并将其传递给您的 React 应用程序,然后继续将它与您的 React 应用程序正在使用的任何 ajax 库一起传递?你用的是什么 ajax 库?
  • 我应该如何通过它?我不想把它放到 HTML 中;只需将其发送给JS。我可能会使用 fetch 或其他东西。不使用一台自动取款机。
  • 要“发送到 JS”,你将不得不“把它放在 HTML 中”,除非你的 JS 是通过 Jinja 生成的。
【解决方案2】:

你可以将 {{ csrf_token() }} 扔到 index.html 的元标记中

 <meta  id="csrf-token" content={{csrf_token()}}>

那么当你想发布/获取时, 只需使用

将其添加到您的标题中
export const post = (path, data={}) => {

const options = {
    method: 'POST', 
    headers: {
        // 'Accept': 'application/json; charset=utf-8',
        // 'Content-Type': 'application/json; charset=utf-8',
        // 'Cache': 'no-cache',
        // 'X-Requested-With': 'XMLHttpRequest', 
        'X-CSRFToken': document.getElementById("csrf-token").getAttribute("content")
    }, 
    body: data
};

return fetch(path, options);
}

附言这仍然感觉很老套,我仍在寻找一种反应更快的方法

【讨论】:

  • 是的,我可能不应该接受其他答案。自从我写了这个问题以来,我没有使用过烧瓶或处理过 csrf 保护(我最终放弃了那个特定的项目),但我认为你的解决方案会奏效!
猜你喜欢
  • 2013-05-24
  • 2014-02-25
  • 2020-09-26
  • 2015-11-27
  • 2017-01-08
  • 2018-03-11
  • 1970-01-01
  • 2014-03-15
  • 2016-11-08
相关资源
最近更新 更多