A login system needs to check passwords without storing them in readable form. A cryptographic hash turns a password into a stored value that cannot be used to read back the original password. section 8.2.1
Keep that work inside the user model: setting `User.password` generates a cryptographically strong hash and stores it as `hashed_password`. Reading `User.password` raises an attribute error. When someone logs in, `verify_password()` checks the submitted password against the stored hash. section 8.2.1
class User(UserMixin, db.Model): #1
__tablename__ = "user" #2
user_uid = db.Column(db.String, primary_key=True, default=get_uuid) #3
first_name = db.Column(db.String, nullable=False) #4
last_name = db.Column(db.String, nullable=False) #4
email = db.Column(db.String, nullable=False, #4
unique=True, index=True) #4
hashed_password = db.Column("password", #4
db.String, nullable=False) #4
active = db.Column(db.Boolean, nullable=False, default=False) #4
created = db.Column(db.DateTime, nullable=False, #5
default=datetime.utcnow) #5
updated = db.Column(db.DateTime, nullable=False, #5
default=datetime.utcnow, onupdate=datetime.utcnow) #5
def get_id(self):
return self.user_uid
@property
def password(self):
raise AttributeError("user password can’t be read")
@password.setter
def password(self, password):
self.hashed_password = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.hashed_password, password)
def __repr__(self):
return f"""
user_uid: {self.user_uid}
name: {self.first_name} {self.last_name}
email: {self.email}
active: {'True' if self.active else 'False'}
"""
The model stores `hashed_password` in a database column named `password`; the attribute name makes its contents clearer in application code. section 8.2.1



