检查数据库中的现有用户 return user if exists return false if user does not exist

Checking for an existing user in a database return user if exists return false if user does not exist

我正在为我的烧瓶应用程序重构 app.py。我正在尝试让 user.py class 处理所有与用户相关的事情。如果我的数据库中不存在该用户,我应该如何将 user.py class 构造为 return false?

app.py:

  db = get_db_connection() 
  user = User(db, request.form.get("email"))
  if not user.get_email(): # If user does not exist send user to registration page
     return redirect("/register", email=request.form.get("email")) # go to the registration page and fill in the used e-mail address
  
  # Check password and send to user_index if correct
  password = request.form.get('password')
  if user.check_password(password):
     session['userID'] = user.get_id()
     session['name'] = user.get_first_name()
     session['email'] = user.get_email()
     return redirect("/user_index")
  return message("Wrong Password. Go to log in page to try again.")

user.py:

class User:
    def __init__(self, database, email):
        db = database

        user = db.execute("SELECT * FROM users WHERE users.email = ?", [email]).fetchall()

        if user:
            self.__id = user['id']
            self.__last_name = user['lastName']
            self.__first_name = user['firstName']
            self.__email = user['email']
            self.__date_of_birth = user['dateOfBirth']
            self.__hash = user['hash']

我明白当我在 python 中实例化一个对象时,它应该 return none。我如何构建我的代码,以便如果具有给定电子邮件的用户不存在,我可以获得某种类型的错误值?一旦我得到一个错误的值,我应该能够将用户重定向到注册页面。

如果我做的完全错了,请指出正确的方向。

这里有很多要说的:

  1. 我建议将 SQLAlchemy 之类的 ORM 与 Flask 一起使用。它会让你的生活更轻松,你不必担心一些安全问题(例如 SQL 注入)。
  2. 如果用户要登录,如果他们的电子邮件或密码不正确,最好return消息“错误的凭据”,这样攻击者就不知道哪个是正确的或不正确,因此他们将有很多很多组合来尝试。也就是说,只需将短语“错误的密码”更改为“错误的凭据”,您就可以掩盖应用程序中的安全漏洞。如果用户未注册,则应 return 编辑相同的消息。
  3. 我建议您继续阅读 uses of underscore in Python,因为您显然是在不需要它的地方使用它。
  4. 在 Python 中,您不需要使用 getter 和 setter,除非您需要在获取或设置属性之前进行一些预处理。

最后,在 Flask 中,这是构建小型项目的常用方法:

__init__.py

from flask import Flask

from utils import get_db_connection


app = Flask(__name__)
db = get_db_connection()

utils.py

# Do the necessary imports.


def get_db_connection():

    ...

run.py

from . import app


if __name__ == "__main__":
    app.run()  # You can set multiple settings in run().

routes.py

from . import app
from user import User


@app.route("/login", methods=["POST"])
def login():

    user = User.get(request.form.get("email"))

    # This is not recommended.
    # if not user:
    #     return redirect("/register", email=request.form.get("email"))

    password = request.form.get('password')

    if user and user.check_password(password):
        session['userID'] = user.id
        session['name'] = user.first_name
        session['email'] = user.email

        return redirect("/user_index")

    return message("Wrong credentials. Go to log in page to try again.")

models.py

from . import db


class User:

    def __init__(self, id, last_name, first_name, email, date_of_birth, hash):

        self.id = id
        self.last_name = last_name
        self.first_name = first_name
        self.email = email
        self.date_of_birth = date_of_birth
        self.hash = hash
    
    def check_password(self, password):

        return check_password_hash(self.hash, password)
    
    @staticmethod
    def get(email):

        user_result = db.execute("SELECT * FROM users WHERE users.email = ?", [email]).fetchall()

        if user_result:
            return User(user_result['id'], user_result['lastName'], user_result['firstName'], 
                        user_result['email'], user_result['dateOfBirth'], user_result['hash'])
        
        return None


# Declare more classes for your database models!
# class Admin:
#
#    ...