【问题标题】:Flask CSRF token missing [duplicate]Flask CSRF令牌丢失[重复]
【发布时间】:2021-11-23 16:34:44
【问题描述】:

我试图在我的网站上使用 csrf 保护,但没有成功。 我正在做documentation 所说的一切,但它仍然说我缺少 csrf 会话令牌。 当我尝试在 html 页面上打印 csrf 令牌时,它确实显示有一个并将其打印在页面上。

我正在尝试解决这个问题 2 天,但我找不到解决方案。

我的代码:

app = Flask(__name__)
csrf = CSRFProtect(app)
app.config["SECRET_KEY"] = 'secret'

@app.route("/reserve", methods=["GET", "POST"])
def reserve():
   if request.method == "GET" :
       return render_template("reserve.html"))


<form id="Reserve" action="/reserve" method="post">
   <!-- csrf protection -->
   <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
   <input type="text" placeholder="Name">
   <button type="submit">
        Submit
   </button>
</form>

【问题讨论】:

    标签: python flask session flask-wtforms wtforms


    【解决方案1】:

    如果我理解正确,您的问题是无法在您的视图代码中访问 de csrf 令牌数据。

    我添加了一些代码,以便在收到 POST 请求时从服务器端返回令牌,并且它可以正常工作:

    文件夹结构

      ├── app.py
      └── templates
        └── reserve.html
    

    (默认情况下,Flask 会在项目根目录中的 templates 文件夹中查找)

    app.py

    from flask import Flask, request, render_template
    from flask_wtf.csrf import CSRFProtect
    
    app = Flask(__name__)
    csrf = CSRFProtect(app)
    app.config['SECRET_KEY'] = 'secret'
    
    
    @app.route('/reserve', methods=['GET', 'POST'])
    def reserve():
        if request.method == 'GET':
            return render_template('reserve.html')
    
        if request.method == 'POST':
            return {
                'token': request.form.get('csrf_token')
            }
    
    
    if __name__ == '__main__':
        app.run()
    

    reserve.html

    <form id="Reserve" action="/reserve" method="post">
       <!-- csrf protection -->
       <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
       <input type="text" placeholder="Name">
       <button type="submit">
            Submit
       </button>
    </form>
    

    启动服务器:

    $ python app.py 
     * Serving Flask app 'app' (lazy loading)
     * Environment: production
       WARNING: This is a development server. Do not use it in a production deployment.
       Use a production WSGI server instead.
     * Debug mode: off
     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    

    然后在浏览器中打开这个网址:http://127.0.0.1:5000/reserve

    如果您检查 HTML 表单,您会看到如下内容:

    <input type="hidden" name="csrf_token" value="IjZkNGZhMTI1MGVmNWUzZDA4OGEwOThlZjZiODIxMGY3MTljYjBiNWUi.YVg1pA.EzPIPEqadPoq8oZQNxWpi33WRqk">
    

    提交输入值,你会看到接收到的token和隐藏输入中渲染的值是一样的:

    {"token":"IjZkNGZhMTI1MGVmNWUzZDA4OGEwOThlZjZiODIxMGY3MTljYjBiNWUi.YVg1pA.EzPIPEqadPoq8oZQNxWpi33WRqk"}
    

    【讨论】:

    • 我是否正确理解了您的答案,它对您有用并且您无法重现该问题?
    • 是的。此代码适用于我,我无法重现 OP 问题。
    猜你喜欢
    • 2018-03-11
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    相关资源
    最近更新 更多