【问题标题】:Flask-WTF CSRF token is missingFlask-WTF CSRF 令牌丢失
【发布时间】:2018-03-11 21:12:29
【问题描述】:

按照 flask-wtf (v. 0.14.2, python 3.4.6) here 的文档,当通过一个简单的单选按钮对 onchange 事件做出反应时,我收到 CSRF token is missing 400 错误。

<script type="text/javascript">
// Send the status of the radio buttons using AJAX
function radio_changed(){
  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);
            }
        }
    });
    var radioValue = $("input[class=radios]:checked").val();
   //alert(radioValue);
   $.ajax({
                    url: '/_radio_update',
                    data: {value:radioValue},
                    type: 'POST',
                    success: function(response){
                            console.log(response);
                    },
                    error: function(error){
                            console.log(error);
                    }
            });
}
</script>

后来

<form method=post action="">
{{ form.csrf_token }}
...

在 Flask 方面:

...
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.secret_key = 'shhhhhhh!'
csrf = CSRFProtect(app)

@app.route('/_radio_update', methods=['GET', 'POST'])
def _radio_update(radiostatus):
    print(radiostatus)
...

我错过了什么吗?

【问题讨论】:

  • 浏览器是否真的发送令牌?检查开发工具中的网络选项卡。如果不是,是因为this.crossDomain 是真的吗?
  • 在网络下 --> 标头 --> 请求标头 我只看到一个会话 cookie,没有令牌。我也尝试了crossDomain:false,结果相同。还尝试了jsonp,如tutorial 中所述,也没有帮助。能详细点吗?
  • 如果服务器说它看不到 CSRF 令牌,要么不存在,要么服务器存在错误。我们只是将其缩小到不存在的令牌,特别是浏览器不发送它。接下来,您可以逐行跟踪 JavaScript 以查看未按计划进行的地方。
  • 好的,但只是为了再次确保在调试 JS 时出现正确行为时我应该看到什么:如果发送了令牌,它将出现在请求标头部分中,对吗?它会是什么样子?
  • 您将拥有一个带有一些随机值的 X-CSRFToken 标头。

标签: python flask csrf flask-wtforms


【解决方案1】:

wtforms 导入的Forms 和从flask.ext.wtf 导入的Forms 之间似乎存在差异,根据documentation 末尾的注释会导致问题。

在处理了弃用通知后,最后我改变了这一行:

from wtforms import Form, RadioField, SubmitField, validators
class InputForm(Form):
...

from wtforms import RadioField, SubmitField, validators
from flask_wtf import FlaskForm
class InputForm(FlaskForm):
...

这解决了我的问题。

【讨论】:

    猜你喜欢
    • 2017-05-24
    • 2017-01-08
    • 2021-11-23
    • 1970-01-01
    • 2020-07-15
    • 2020-11-23
    • 2017-09-27
    • 1970-01-01
    • 2018-07-16
    相关资源
    最近更新 更多