当在flask应用程序中使用wtform时,如何解决错误KeyError: 'A secret key is required to use CSRF.'?

43

我一直在尝试使用Flask、WTForms和Firebase数据库构建Web应用程序,但是我不断收到错误消息:“KeyError:'A secret key is required to use CSRF。'”,而我不知道如何解决它。 以下是我的代码:

from flask import Flask, render_template, request
from firebase import firebase
from flask_wtf import FlaskForm
from flask_wtf.csrf import CSRFProtect, CSRFError
from wtforms import DateField, StringField, TextAreaField
from wtforms.validators import DataRequired
from wtforms_components import TimeField



app = Flask(__name__)

csrf = CSRFProtect(app)


firebase = firebase.FirebaseApplication("https://uhungry-f9563.firebaseio.com", None)

class myForm(FlaskForm):
        event = StringField("event", validators=[DataRequired()])
        location = StringField("location", validators=[DataRequired()])
        startDay = DateField("startDay", validators=[DataRequired()])
        startTime = TimeField("startTime", validators=[DataRequired()])
        endDay = DateField("endDay", validators=[DataRequired()])
        endTime = TimeField("endTime", validators=[DataRequired()])
        details = TextAreaField("details", validators=[DataRequired()])


count = 0

@app.route('/', methods=['GET' , 'POST'])
def home():
    form = myForm()
    if form.validate_on_submit():
        global count
        count += 1
        putData = {'Event': form.event.data, 'Location': form.location.data, 'startDay': form.startDay.data, 'startTime': form.startTime.data,'endDay': form.endDay.data, 'endTime': form.endTime.data, 'Details': form.details.data}
        firebase.put('/events', 'event' + str(count), putData)
        return render_template("trial.html")
    return render_template("home.html")

if __name__ == '__main__':
    app.run(debug=True)

请参考此链接:https://dev59.com/J2Ei5IYBdhLWcg3wNqHN - Amit Tripathi
5个回答

61

您收到此错误是因为您尚未设置秘密密钥。没有秘密密钥,您将无法使用许多功能,例如flash、flask-login和当然,正如您所经历的那样,CSRF保护。

最简单的解决方法是在您的应用程序配置文件中设置一个秘密密钥,但与其他答案所示的不同,强烈建议将所有密钥(特别是一些付费API或服务的密钥,例如AWS)保存在一个独立的.env文件中,该文件在代码分发时不共享。幸运的是,对于秘密密钥,您不必担心环境变量,您只需按以下方式创建随机秘密密钥即可:

import os
SECRET_KEY = os.urandom(32)
app.config['SECRET_KEY'] = SECRET_KEY

2
不知道 os.urandom(32)。谢谢! - ryentzer
如果文件被加密,你仍然可以分享它。在 Flask 初始化时,需要对其进行解密。 - KeyC0de

12

您需要在应用程序配置中添加一个SECRET_KEY以利用csrf保护并提供一个WRF CSRF SECRET_KEY,否则将使用您的密钥。

app.config.update(dict(
    SECRET_KEY="powerful secretkey",
    WTF_CSRF_SECRET_KEY="a csrf secret key"
))

app = Flask(name) app.config.update(dict( SECRET_KEY="强大的秘钥", WTF_CSRF_SECRET_KEY="一个CSRF秘钥" )) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///某个数据库文件.db' db = SQLAlchemy(app) csrf = CSRFProtect(app) csrf.init_app(app) - Ferda-Ozdemir-Sonmez
当我尝试打开路径时,仍然会出现“需要秘密密钥才能使用CSRF”的RuntimeError错误。 - Ferda-Ozdemir-Sonmez
我错过了什么?请问,你能告诉我吗? - Ferda-Ozdemir-Sonmez

8
将以下代码行添加到您的app代码中:
app.config['SECRET_KEY'] = 'any secret string'

2
在我的情况下(Python 3.8.1ArchLinuxflask 1.1.1,调试模式),我不得不在 app = Flask(__name__) 后面立即添加命令才能使其工作。具有此错误的示例应用程序在此处:https://pastebin.com/fPeE9J2G(我将 cmd 插入到第32行)。如果我将其移动到第8行,则一切正常。 - dmitry_romanov

0
你需要像这样添加秘钥:
from flask import Flask, session

app = Flask(__name__)
app.secret_key = secret_key  # Set the secret key for the Flask application

@app.route('/')
def index():
    # Your view logic here
    pass

0
我通过在config.py文件中添加SECRET_KEY = 'mysecret'来解决了这个问题,然后确保在调用create_app()时添加了配置。
env = os.environ.get('FLASK_ENV', 'dev')

app = create_app('app.config.%sConfig' % env.capitalize())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,