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

问题描述 投票:0回答:2

嗨,优秀的程序员。我只是尝试从注册表中获取输入,通过根据 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>

这是我的login.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>

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

forms validation flask mysql-workbench
2个回答
0
投票

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

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
投票

我相信这是导致错误的原因:

    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 DB 中是否存在该电子邮件即可。我们不需要第二次检查(使用 == 运算符)

© www.soinside.com 2019 - 2024. All rights reserved.