Защита от CSRF с помощью формы React, сервера Flask и Flask-WTF

TL;DR Мне нужно защитить свою форму от CSRF-атак, и я хочу использовать ReactJS для внешнего интерфейса и Flask/Flask-WTF для внутреннего интерфейса.

Я рефакторинг веб-сайта, созданного с помощью Python, Flask и Flask-WTF для форм, и я хочу использовать React для внешнего интерфейса, а не Jinja2 через PyPugjs. Я использую 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}

person Hum4n01d    schedule 24.03.2017    source источник
comment
Скорее вопрос должен звучать так: «Как мне добавить поле ввода с помощью React + Python». Защита от CSRF — это просто поле со случайным значением, которое предоставляется, а затем проверяется сервером.   -  person marco-a    schedule 27.03.2017


Ответы (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);
}

p.s. это все еще кажется хакерским, и я все еще ищу более реактивный способ

person blah blah    schedule 12.05.2020
comment
Да, я, вероятно, не должен был принимать этот другой ответ. Я не использовал flask и не имел дело с защитой csrf с тех пор, как написал этот вопрос (в итоге я отказался от этого конкретного проекта), но я думаю, что ваше решение сработает! - person Hum4n01d; 13.05.2020

Вам нужно будет отправить токен csrf в качестве заголовка X-CSRFToken при отправке формы. См. их документы здесь: http://flask-wtf.readthedocs.io/en/stable/csrf.html#javascript-requests

Их пример с отправкой POST через jQuery устанавливает X-CSRFToken перед отправкой любых запросов POST/PUT/DELETE ajax:

<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 будет отличаться.

person kavun    schedule 29.03.2017
comment
Что ж, это интересно, но мне нужно знать, как реализовать это с помощью React. Не могли бы вы помочь мне с этим? - person Hum4n01d; 31.03.2017
comment
Кроме того, я не хочу использовать Jinja для встраивания токена CSRF. Разве нет лучшего способа? @кавун - person Hum4n01d; 31.03.2017
comment
@ Hum4n01d визуализирует токен CSRF и передает его в ваше приложение React, а затем продолжает передавать его вместе с любой ajax-библиотекой, которую использует ваше приложение React? Какую библиотеку ajax вы используете? - person kavun; 05.04.2017
comment
Как я должен пройти это все же? Я не хочу помещать это в HTML; просто отправьте его в JS. Я бы, наверное, использовал выборку или что-то в этом роде. Не используя один банкомат. - person Hum4n01d; 05.04.2017
comment
чтобы отправить его в JS, вам нужно будет поместить его в HTML, если только ваш JS не сгенерирован через Jinja. - person kavun; 05.04.2017
comment
нет ли другого способа сделать это? - person Hum4n01d; 06.04.2017
comment
Я бы хотел, чтобы этот ответ не был принят, потому что он неуместен и не отвечает на вопрос реализации реакции. это просто прямо из документа WTF Forms - person blah blah; 10.05.2020