使用 MySQL 数据库进行 Flask 表单身份验证验证

Flask Form Authentication validation with MySQL database

提问人:Motchello 提问时间:11/14/2023 最后编辑:esqewMotchello 更新时间:11/16/2023 访问量:85

问:

嗨,好的程序员。我只是尝试从寄存器表单中获取输入,通过根据 MySQL-workbench 数据库验证它们来检查和确认它们。注意,我对 Flask 和 python 相当陌生。

我的期望:

如果输入电子邮件存在,请路由并停留在注册上,否则路由登录。 但是该应用程序只是不断获取输入并将它们发送到数据库,即使它是相同的信息。

提前致谢 莫切洛

这是我下面的代码

from flask import Flask
from flask import render_template, url_for
from flask import request, redirect
from sqlalchemy import String, Integer, CHAR
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import Session
from flask_sqlalchemy import SQLAlchemy

# import flask login
from flask_login import UserMixin


# create an inheritance class from DeclarativeBase
class Base(DeclarativeBase):
    pass


# instan
db = SQLAlchemy(model_class=Base)

SESSION_TYPE = 'sqlalchemy'
app = Flask(__name__)

# Create a connection to the database using mysql and + pymysql
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@localhost/New_User_Database'
# config secrete key
app.config['SECRET_KEY'] = 'TooTopSecrete'

# initialize database app
db.init_app(app)

session = Session(app)


# Create a Table class using flask_sqlaclhemy
class Users(db.Model, UserMixin):
    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    username: Mapped[str] = mapped_column(String(30), unique=True, nullable=False)
    email: Mapped[str] = mapped_column(String(30))
    password: Mapped[str] = mapped_column(CHAR(80))


with app.app_context():
    db.create_all()


# view route page for home
@app.route('/', methods=['GET'])
def home():
    return render_template('login.html')


# view route page for login
@app.route('/login', methods=['GET', 'POST'])
def login():
    return render_template('login.html')


# view route page for sign up
@app.route('/sign_up', methods=['GET', 'POST'])
def sign_up():
    if request.method == 'POST':
        user_email = request.form.get('email', False)
        email_in_database = Users.query.filter_by(email=Users.email).first()
        if user_email == email_in_database:
            return redirect(url_for('sign_up'))
        else:
            new_user = Users(
                username=request.form['username'],
                email=request.form['email'],
                password=request.form['password'],
            )
            db.session.add(new_user)
            db.session.commit()

            return redirect(url_for('login', ))

    return render_template('sign_up.html')


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

这是我sign_up.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> Sign up</title>
    <style>

        input[type=email], select {
          width: 100%;
          padding: 12px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 4px;
          box-sizing: border-box;
        }

        input[type=password], select {
          width: 100%;
          padding: 12px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 4px;
          box-sizing: border-box;
        }

        input[type=text], select {
          width: 100%;
          padding: 12px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 4px;
          box-sizing: border-box;
        }

        input[type=submit] {
          width: 100%;
          background-color: #4CAF50;
          color: white;
          padding: 14px 20px;
          margin: 8px 0;
          border: none;
          border-radius: 4px;
          cursor: pointer;
        }

        input[type=submit]:hover {
          background-color: #45a049;
        }

        div {
          border-radius: 5px;
          background-color: #f2f2f2;
          padding: 20px;
        }
</style>
</head>
<body>

    <h1> Sign up </h1>

    <div>

        <form method="post" action="/sign_up" autocomplete="on">
        <input type="text" id="username" name="username" maxlength="40"
               placeholder="username" autofocus required><br><br>

        <input type="email" id="email" name="email" maxlength="40"
               placeholder="email" required><br><br>

        <input type="password" id="password" name="password" maxlength="64" min="6"
               placeholder="password" required><br><br>

        <input type="submit" value="Sign up"><br><br>
    </form>

        <form method="get" action="{{ url_for('login') }}" >

            <p> Already have an account? <a href="{{ url_for('login') }}"> LOGIN  </a></p><br>

        </form>


    </div>


</body>
</html>

这是我的登录名.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> login </title>
    <style>

        input[type=email], select {
          width: 100%;
          padding: 12px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 4px;
          box-sizing: border-box;
        }

        input[type=password], select {
          width: 100%;
          padding: 12px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 4px;
          box-sizing: border-box;
        }

        input[type=submit] {
          width: 100%;
          background-color: #4CAF50;
          color: white;
          padding: 14px 20px;
          margin: 8px 0;
          border: none;
          border-radius: 4px;
          cursor: pointer;
        }

        input[type=submit]:hover {
          background-color: #45a049;
        }

        div {
          border-radius: 5px;
          background-color: #f2f2f2;
          padding: 20px;
        }
</style>
</head>
<body>

    <h1> Login </h1>
    <div>
         <form method="post" action="{{ url_for('login') }}" autocomplete="on">

            <input type="email" id="email" name="email" maxlength="40"
                   placeholder="email" required><br><br>

            <input type="password" id="password" name="password" maxlength="64" min="6"
                   placeholder="password" required><br><br>



            <input type="submit" value=" Login "><br><br>

        </form>

        <form method="get" action="{{ url_for('sign_up') }}" >

            <p> Don't have an account? <a href="{{ url_for('sign_up') }}"> SIGN UP  </a></p><br>

        </form>

    </div>



</body>
</html>

我已经浏览了一些堆栈溢出的答案,并用谷歌搜索了一下,但无济于事。感谢所有的帮助。

MySQL 表单 验证 Flask

评论

0赞 Motchello 11/14/2023
有没有可能有帮助的身体?
0赞 Matthias 11/15/2023
请打印这两个变量,看看为什么它们不相同,也许其中一个只是小写或类似的东西: 和print('user email:', user_email)print('email in db:', email_in_database)
0赞 Motchello 11/15/2023
嗨@Mathias,这是打印输出 - :用户电子邮件 = [email protected] db 中的电子邮件 = <用户 4>。谢谢
0赞 Motchello 11/15/2023
它似乎正在打印出模型和 id。

答:

0赞 Matthias 11/15/2023 #1

我建议的解决方案,将这些行更改为:

user_email = request.form.get('email', False)
user_from_db = Users.query.filter_by(email=user_email).first()
if user_from_db:
    return redirect(url_for('sign_up'))
else:
    # same code you had before

原因是您从数据库中获取了一个用户,并将其称为电子邮件。但是,如果第一个用户使用您指定的电子邮件,或者如果它不存在,则返回。Users.query.first()None

然后你把那个用户和电子邮件比较了,这是不正确的,你基本上是在说

if "[email protected]" == None

if "[email protected]" == {id:..., email: the actual email, password=""}

这就是为什么我认为您想要实现的目标可以在几乎没有变化的情况下完成,方法是通过电子邮件获取该用户,然后说

if user_from_db:

当有用户时,这将是真实的,但如果是,这将是假的(数据库中没有该电子邮件的用户)。None

我认为还有其他事情是错误的,你说我不确定到底是什么,可能尝试按非字符串过滤?它似乎没有错误,所以谁知道呢,也许它会适用于您的旧线路。但是我将其更改为表格中的电子邮件。这就是说“使用表单中的电子邮件从数据库中获取我的用户”。filter_by(email=Users.email)filter_by(email=user_email)

一些建议:

  • 你真的需要学习如何自己调试这些东西,在 python 中查找调试,有两种主要方法,使用调试器,比如 pdb 或将打印命令放在程序的关键点(或两者兼而有之)。

  • 你需要知道你的程序中发生了什么,就像这里一样,你试图比较一个字符串和一个没有意义的对象,但是通过一些打印命令,你可以看到你的程序中实际发生了什么。

评论

0赞 Motchello 11/16/2023
谢谢。这真的很有帮助。它有效,并且会高度使用您推荐的建议。
0赞 seyf97 11/15/2023 #2

我相信这导致了错误:

user_email = request.form.get('email')
email_in_database = Users.query.filter_by(email=Users.email).first()
if user_email == email_in_database:

请尝试以下操作:

user_email = request.form.get('email')
email_in_database = Users.query.filter_by(email=user_email).first()
if email_in_database:

从本质上讲,我们只需要检查电子邮件是否存在于 SQL 数据库中。我们不需要第二次检查(与操作员一起)==

评论

0赞 Motchello 11/16/2023
谢谢。此解决方案有效。我很感激,也很谦卑。我相信我将来会遇到更多问题,但会按照建议学习调试方法。