这是我通过登录表单验证得到的消息:
session: <SecureCookieSession {}>
request.form: ImmutableMultiDict([('eventid', ''), ('csrf_token', 'ImI1N2EwYjFjZmIxZDI4YjQ3ZTIxM2VmNGNkOGQzZTEzYzBiM2U4MzEi.DsNqRA.sw618M5laiwyElfOJ9mAIAAOXig'), ('password', 'admin'), ('username', 'admin'), ('submit', 'Sign In')])
INFO:flask_wtf.csrf:The CSRF tokens do not match.
127.0.0.1 - - [06/Nov/2018 19:18:57] "POST / HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [06/Nov/2018 19:18:57] "POST / HTTP/1.1" 200 -
我打印表单数据和session
,结果显示该会话为空。
我了解到,该会话必须具有令牌,但令牌已丢失,并且我不知道要在会话中获取所需数据该怎么做。我遵循了this tutorial,似乎所有这些都必须自动设置。
以前,我没有使用flask_wtf
,而且一切正常。我检查了所有有关令牌不匹配或令牌丢失的问题,但无法使用他们的建议解决问题。
这是我的文件:
__ init __。py
#!/usr/bin/env python3
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
# register blueprints
from app.auth import auth
app.register_blueprint(auth.bp)
视图: auth.py
from flask import (
Blueprint,
flash,
g,
redirect,
render_template,
request,
session,
url_for,
)
from werkzeug.security import check_password_hash, generate_password_hash
from app import db
from app.auth.forms import LoginForm
from app.models import User
bp = Blueprint('auth', __name__)
@bp.route('/', methods=('GET', 'POST'))
@bp.route('/login/', methods=('GET', 'POST'))
def login():
print('session:', session)
form = LoginForm()
print('request.form:', request.form)
if form.validate_on_submit():
print('Form is valid')
eventid = form.eventid.data
username = form.username.data
password = form.password.data
# validate login
user = User.query.filter_by(username=username.lower()).first()
error = None
if not user or not check_password_hash(user.password, password):
error = 'Incorrect username-password combination.'
if not error:
session.clear()
session['user_id'] = user.id
return redirect(url_for('performance.index'))
flash(error)
return render_template('auth/login.html', title='Sign In', form=form)
表格: forms.py
from flask_wtf import FlaskForm
from wtforms import (
BooleanField,
PasswordField,
StringField,
SubmitField,
)
from wtforms.validators import DataRequired
class LoginForm(FlaskForm):
eventid = StringField('Event ID')
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Sign In')
模板: login.html
{% extends 'base.html' %}
{% block header %}
<h3>{% block title %}{{ title }}{% endblock %}</h3>
{% endblock %}
{% block content %}
<form action="" method="post">
<div class="form-group">
<label class="col-sm-12" for="username">
{{ form.username.label }}
</label>
{{ form.username() }}
</div>
<div class="form-group">
<label class="col-sm-12" for="password">
{{ form.password.label }}
</label>
{{ form.password() }}
</div>
<div class="form-group">
<label class="col-sm-12" for="eventid">
{{ form.eventid.label }}
</label>
{{ form.eventid() }}
</div>
<div class="form-group">
{{ form.submit }}
</div>
{{ form.hidden_tag() }}
</form>
{% endblock %}
配置: config.py
import os
class Config:
instance_path = '/some/path/to/instance/'
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
DATABASE = os.path.join(instance_path, 'app.sqlite')
SQLALCHEMY_DATABASE_URI = ('sqlite:///' + os.path.join(instance_path,
'app.sqlite'))
SQLALCHEMY_TRACK_MODIFICATIONS = False
我已经尝试了所有命题,但是我发现:
-我在模板中设置了hidden_tag()
;
-我在配置中设置了SECRETE_KEY
;
-我尝试将FlaskForms
更改为Forms
;
-其他解决方案。
他们都没有帮助。我已经和它坐了三个晚上。任何建议都会很好。
更新
如果我不使用Blueprint
,即如果我在@app.route(...)
中使用@bp.route(...)
而不是auth.py
,尽管{{1} }仍然为空。因此,现在我不了解蓝图的问题。
答案 0 :(得分:0)
我认为您从教程中跳过了这一部分:
form.hidden_tag()模板参数生成一个隐藏字段,该字段包含用于保护表单免受CSRF攻击的令牌。要保护表单,您需要做的就是包括此隐藏字段,并在Flask配置中定义 SECRET_KEY 变量。如果您照顾好这两件事,Flask-WTF会为您完成其余的工作。
因此,在您的配置文件中,应该设置秘密密钥
import os
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
如果这不起作用,请在您的 login.html 中,尝试像这样添加 csrf_token 表单的开头:
<form action="" method="post">
{{ form.csrf_token }}
<div class="form-group">
<label class="col-sm-12" for="username">
{{ form.username.label }}
.....
答案 1 :(得分:0)
我遇到了同样的问题,只有我能看到的更好的东西
127.0.0.1 - - [08/Oct/2020 09:27:00] "GET /add_faqs HTTP/1.1" 200 -
------ ImmutableMultiDict([('csrf_token', 'IjQzNTE4ZmIwMDFjMGM3MjAwOWEwNWQwYjUxOTEyNTJlYTc0OTU2Mzki.X38TpA.rvc1178AkNAvgLN_PbsHWKpra60'), ('question', 'test111'), ('answer', 'test1'), ('display_order', '1')])
session: <SecureCookieSession {'csrf_token': '7967a78759d4cbfb255d56e2a9092bfe2d75e17d'}>
令牌是不同的。不确定为什么。