首页 > 解决方案 > RuntimeError:使用 CSRF 需要密钥。我使用了一个密钥,但它似乎仍然给出了错误

问题描述

这是我在制作 web 应用程序时包含在flask_blog.py中的代码。我已经提到了 SECRET_KEY。任何人都可以查看它并让我知道此代码中可能出现的错误。提前致谢。

from flask import Flask, render_template, url_for, flash, redirect
from forms import RegistrationForm, LoginForm

app = Flask(__name__)
app.config['SECRET_KEY']='key'
posts=[
    {
        'author':'HC Verma',
        'title':'First blog Post',
        'content':'first post content'
    },
    {
        'author':'RD Sharma',
        'title':'Second blog Post',
        'content':'second post content'
    }
]


@app.route("/")
@app.route("/home")
def home():
    return render_template('home.html', posts=posts)


@app.route("/about")
def about():
    return render_template('about.html', title='About')


@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        flash(f'Account created for {form.username.data}!', 'success')
        return redirect(url_for('home'))
    return render_template('register.html', title='Register', form=form)


@app.route("/login", methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        if form.email.data == 'abc@gmail.com' and form.password.data == 'password':
            flash('You have been logged in!', 'success')
            return redirect(url_for('home'))
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html', title='Login', form=form)


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

编辑:这是我面临的运行时错误,我在此处添加了屏幕截图的链接。 截屏

还添加了具有 RegistrationForm 和 LoginForm 类的 forms.py 文件。

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, 
   BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo


class RegistrationForm(FlaskForm):
    username = StringField('Username',
                           validators=[DataRequired(), Length(min=2, 
    max=20)])
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password',
                                     validators=[DataRequired(), 
    EqualTo('password')])
    submit = SubmitField('Sign Up')


class LoginForm(FlaskForm):
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember = BooleanField('Remember Me')
    submit = SubmitField('Login')

编辑:2 这是两个模板 1)register.html-制作注册页面的模板

{% extends "layout.html" %}
{% block content %}
    <div class="content-section">
        <form method="POST" action="">
            {{ form.hidden_tag() }}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Join Today</legend>
                <div class="form-group">
                    {{ form.username.label(class="form-control-label") }}

                    {% if form.username.errors %}
                        {{ form.username(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.username.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.username(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.email.label(class="form-control-label") }}
                    {% if form.email.errors %}
                        {{ form.email(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.email.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.email(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.password.label(class="form-control-label") }}
                    {% if form.password.errors %}
                        {{ form.password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.password(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.confirm_password.label(class="form-control-label") }}
                    {% if form.confirm_password.errors %}
                        {{ form.confirm_password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.confirm_password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.confirm_password(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>
    <div class="border-top pt-3">
        <small class="text-muted">
            Already Have An Account? <a class="ml-2" href="{{ url_for('login') }}">Sign In</a>
        </small>
    </div>
{% endblock content %}
  1. login.html-制作登录页面的模板

         {% extends "layout.html" %}
     {% block content %}
         <div class="content-section">
             <form method="POST" action="">
                 {{ form.hidden_tag() }}
         <fieldset class="form-group">
             <legend class="border-bottom mb-4">Log In Page</legend>
                      <div class="form-group">
                         {{ form.email.label(class="form-class-label") }}
                         {% if form.email.errors %}
                         {{ form.email(class="form-control form-control-lg is-invalid") }}
                         <div class="invalid-feedback">
                             {% for error in form.password.errors %}
                             <span> error </span>
                             {% endfor %}
                         </div>
                         {%else%}
     {   (class="form-control form-control-lg") }}
                         {% endif %}
                     </div>
                     <div class="form-group">
                         {{ form.password.label(class="form-class-label") }}
                         {% if form.password.errors %}
                         {{ form.password(class="form-control form-control-lg is-invalid") }}
                         <div class="invalid-feedback">
                             {% for error in form.password.errors %}
                             <span>{{error}} </span>
                             {% endfor %}
                         </div>
                         {%else%}
     {                       {{ form.password(class="form-control form-control-lg") }}
                         {% endif %}
                     </div>
                    <div class="form-check">
                     {{ form.remember(class="form-check-input") }}
                     {{ form.remember(class="form-class=label") }}
                    </div>
         </fieldset>
         <div class="form-group">
             {{ form.submit(class="btn btn-outline-info") }}
         </div>
         <small class="text-muted ml-2"> 
             <a href="#">
                 Forgot Password?
             </a></small>
         </form>
    
         </div>
         <div class="border-top pt-3">
             <small class="text-muted">
                 Need an account? Log in <a class="ml-2" href="{{ url_for('register') }}">
                 Sign Up</a>
             </small>
         </div>
    
     {% endblock content %}
    

我已按照评论中的要求添加了文件、模板和屏幕截图。让我知道以下代码中有什么问题。

标签: pythonflaskflask-wtforms

解决方案


好的,所以我刚刚尝试了您的代码示例,并进行了一些小改动(但尽管如此,我还没有收到丢失的 SECRET KEY,但请继续阅读)

app.py- 所以在这里我只修改了home端点about,因为我没有这些.html文件,现在只是重定向到register页面。同样在成功登录/注册后registerlogin我也重定向到不同的端点,因为我没有home端点.html文件。

from flask import Flask, render_template, url_for, flash, redirect
from forms import RegistrationForm, LoginForm

app = Flask(__name__)
app.config['SECRET_KEY'] = '84da5b8a39a6d06bf8bc7a60cedcac93'
posts = [
    {
        'author': 'HC Verma',
        'title': 'First blog Post',
        'content': 'first post content'
    },
    {
        'author': 'RD Sharma',
        'title': 'Second blog Post',
        'content': 'second post content'
    }
]


@app.route("/")
@app.route("/home")
def home():
    # return render_template('home.html', posts=posts)
    return redirect(url_for('register'))


@app.route("/about")
def about():
    # return render_template('about.html', title='About')
    return redirect(url_for('register'))


@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        flash(f'Account created for {form.username.data}!', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)


@app.route("/login", methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        if form.email.data == 'abc@gmail.com' and form.password.data == 'password':
            flash('You have been logged in!', 'success')
            return redirect(url_for('register'))
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html', title='Login', form=form)


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

forms.py- 我没有对其进行任何更改。

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo


class RegistrationForm(FlaskForm):
    username = StringField('Username',
                           validators=[DataRequired(), Length(min=2, 
    max=20)])
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password',
                                     validators=[DataRequired(), 
    EqualTo('password')])
    submit = SubmitField('Sign Up')


class LoginForm(FlaskForm):
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember = BooleanField('Remember Me')
    submit = SubmitField('Login')

layout.html- 我创建了自己的渲染registerlogin页面

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>

{% block content %}{% endblock %}

</body>
</html> 

register.html- 没有进行任何更改

{% extends "layout.html" %}
{% block content %}
    <div class="content-section">
        <form method="POST" action="">
            {{ form.hidden_tag() }}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Join Today</legend>
                <div class="form-group">
                    {{ form.username.label(class="form-control-label") }}

                    {% if form.username.errors %}
                        {{ form.username(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.username.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.username(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.email.label(class="form-control-label") }}
                    {% if form.email.errors %}
                        {{ form.email(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.email.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.email(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.password.label(class="form-control-label") }}
                    {% if form.password.errors %}
                        {{ form.password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.password(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.confirm_password.label(class="form-control-label") }}
                    {% if form.confirm_password.errors %}
                        {{ form.confirm_password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.confirm_password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.confirm_password(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>
    <div class="border-top pt-3">
        <small class="text-muted">
            Already Have An Account? <a class="ml-2" href="{{ url_for('login') }}">Sign In</a>
        </small>
    </div>
{% endblock content %}

login.html- 在这里我做了一些更改,首先我修复了登录表单。

  1. 修正 html 错别字:

                  <div class="form-group">
                     {{ form.email.label(class="form-class-label") }}
                     {% if form.email.errors %}
                     {{ form.email(class="form-control form-control-lg is-invalid") }}
                     <div class="invalid-feedback">
                         {% for error in form.password.errors %}
                         <span> error </span>
                         {% endfor %}
                     </div>
                     {%else%}
 {   (class="form-control form-control-lg") }}
                     {% endif %}
                 </div>

                 <div class="form-group">
                    {{ form.email.label(class="form-class-label") }}
                    {% if form.email.errors %}
                    {{ form.email(class="form-control form-control-lg is-invalid") }}
                    <div class="invalid-feedback">
                        {% for error in form.password.errors %}
                        <span> error </span>
                        {% endfor %}
                    </div>
                    {%else%}
                        <div class="form-control form-control-lg"></div>
                    {% endif %}
                </div>
  1. password字段不正确
{                       {{ form.password(class="form-control form-control-lg") }}

变成

{{ form.password(class="form-control form-control-lg") }}
  1. email字段丢失,所以我添加了
{{ form.email(class="form-control form-control-lg") }}

所以最终的结果是这样的:

{% extends "layout.html" %}
{% block content %}
    <div class="content-section">
        <form method="POST" action="">
            {{ form.hidden_tag() }}
    <fieldset class="form-group">
        <legend class="border-bottom mb-4">Log In Page</legend>
                 <div class="form-group">
                    {{ form.email.label(class="form-class-label") }}
                    {% if form.email.errors %}
                    {{ form.email(class="form-control form-control-lg is-invalid") }}
                    <div class="invalid-feedback">
                        {% for error in form.password.errors %}
                        <span> error </span>
                        {% endfor %}
                    </div>
                    {%else%}
                        <div class="form-control form-control-lg"></div>
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.password.label(class="form-class-label") }}
                    {% if form.password.errors %}
                        {{ form.password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.password.errors %}
                            <span>{{error}} </span>
                            {% endfor %}
                        </div>
                    {%else%}
                       {{ form.email(class="form-control form-control-lg") }}
                       {{ form.password(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
               <div class="form-check">
                {{ form.remember(class="form-check-input") }}
                {{ form.remember(class="form-class=label") }}
               </div>
    </fieldset>
    <div class="form-group">
        {{ form.submit(class="btn btn-outline-info") }}
    </div>
    <small class="text-muted ml-2"> 
        <a href="#">
            Forgot Password?
        </a></small>
    </form>

    </div>
    <div class="border-top pt-3">
        <small class="text-muted">
            Need an account? Log in <a class="ml-2" href="{{ url_for('register') }}">
            Sign Up</a>
        </small>
    </div>

{% endblock content %}

因此,您提供的代码工作正常,这意味着您有一个不同的地方出现此错误。即使您已经提供了密钥丢失的可能情况app.config是当您不使用烧瓶jinja2引擎并使用例如 jqueryajax或类似调用发送请求时,这意味着这些不是来自jinja2表单的调用丢失secret key并解决它需要为请求提供密钥 - 为此,您可以在flask-wtf文档中阅读并查看更多示例。


推荐阅读