提问人:Kevinkun 提问时间:1/22/2023 更新时间:1/22/2023 访问量:106
Flask-WTForms 给出错误消息:“CSRF 令牌不匹配。
Flask-WTForms give errors message: "The CSRF tokens do not match."
问:
我以为我终于成功了,直到这个错误被显示出来。csrf_token
我的目标是使用 Flask-WTF 验证表单,但使用 Fetch Javascript 处理它(而不是让 validate_on_submit 函数完成这项工作)。因为我想动态地执行它。
如果验证失败,它将显示输入字段和提交按钮之间的错误。如果成功,它将在其他元素 innerHTML 中显示消息。
当我以空输入提交时,它可以工作。它将像我想要的那样显示消息。但是当我输入有效的电子邮件时,它仍然显示错误消息。"Please enter your email address"
The CSRF tokens do not match
App.py
import os
from flask import Flask, jsonify, flash, redirect, render_template, request, session
from flask_session import Session
from flask_api import status
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import InputRequired
# Configure flask application
app = Flask(__name__)
# Configure Secret Key
app.config["SECRET_KEY"] = "secret123"
# Create Form Class
class AuthenticationForm(FlaskForm):
email = StringField('Email Address', [InputRequired(message="Please enter your email address")])
# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True
# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Configure SQLAlchemy databases
basedir = os.path.abspath(os.path.dirname(__file__))
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + os.path.join(basedir, 'newspaper.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Create SQLAlchemy object of class
class Readers(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
email = db.Column(db.Text, unique=True, nullable=False)
hash = db.Column(db.Text, nullable=False)
def __repr__(self):
return f'<Readers {self.email}>'
@app.after_request
def after_request(response):
"""Ensure responses aren't cached"""
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response
@app.route("/")
def index():
"""Show Newspaper"""
return redirect('/auth/login')
@app.route("/auth/<authentication>", methods=["GET", "POST"])
def auth(authentication):
"""Log user in"""
# Forget any user_id
session.clear()
# Get form class
form = AuthenticationForm()
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
if authentication == 'login':
if form.validate():
data = request.get_json()
email = data["email"]
# Check if email already registered in database
user = Readers.query.filter_by(email=email).first()
if not user:
return "Not Registered Yet", 200
return "Valid!", 200
return jsonify(form.errors), 400
# User reached route via GET (as by clicking a link or via redirect)
return render_template("auth.html", form=form)
auth.html
{% extends "layout.html" %}
{% block title %}
Login -
{% endblock %}
{% block main %}
<div class="auth__form-wrapper">
<div class="auth__title">
<h2>Log in or create an account</h2>
</div>
<div id="success-message"></div>
<form id="form" method="post">
{{ form.csrf_token }}
<fieldset type="email" class="mb-1">
{{ form.email.label }}
{{ form.email(autocomplete="off", autofocus=true, required=false) }}
</fieldset>
<div id="error-message">
<span style="color: red;" id="error"></span>
</div>
<button id="continue" class="btn btn-dark">Continue</button>
</form>
</div>
<script src="{{url_for('static', filename='authentication.js')}}"></script>
{% endblock %}
authentication.js(处理表单提交的文件)
const form = document.querySelector('#form');
const successMessage = document.querySelector('#success-message');
const errorMessage = document.querySelector('#error');
const fields = {
csrf_token: {
input: document.querySelector('#csrf_token')
},
email: {
input: document.querySelector('#email')
}
}
form.addEventListener('submit', async (e) => {
e.preventDefault();
const response = await fetch('/auth/login', {
'method': 'POST',
'headers': {
'Content-Type': 'application/json'
},
'body': JSON.stringify({
'csrf_token': fields.csrf_token.input.value,
'email': fields.email.input.value
})
});
if (response.ok) {
successMessage.innerHTML = await response.text();
} else {
const err = await response.json();
Object.keys(err).forEach((key) => {
errorMessage.innerHTML = err[key][0];
});
}
})
当我使用空输入字段提交时:
当我使用有效的电子邮件提交时:
我不明白。我希望你们能帮上忙。我只想创建一个行为类似于《纽约时报》的表单:NYTForm 登录
答: 暂无答案
评论