liveBook · Manning

Password authentication

As explained in The Well-Grounded Python Developer: How the pros use Python and Flask

A password is a secret character sequence used to authenticate an account or system identity.

A login form is only the visible part of password authentication. The application must check a submitted password against a user account, manage the resulting session, and protect account data if its database is exposed. section 8.2.1

A typical email-and-password login follows these steps:

  • The browser requests the login page with GET, then submits the completed form with POST. section 8.2.1
  • The application uses its user model and storage system to find a matching email and password. section 8.2.1
  • After a successful match, the user goes to the home page or the page they originally wanted to visit. section 8.2.1

Never store user passwords as plain text. Store cryptographic hashes instead: bcrypt makes hashing computationally expensive to resist brute-force attacks. Users who forget their passwords must reset them rather than retrieve them. Flask-Login supplies session management, login and logout tools, and protection for endpoints that require authentication. section 8.2.1

The application may also need its own password to authenticate to another service, such as an SMTP email server. Keep that credential out of source code and public repositories. A separate runtime-accessible file can hold private information, with different versions for development, staging, and production. section 7.6.2

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 User model gives email a unique, indexed field and stores a hashed_password value in the database password column. section 8.2.1

How The Well-Grounded Python Developer: How the pros use Python and Flask covers it

How deep it goes
Traces the login request workflow and explains why passwords are hashed, without detailing bcrypt's algorithm.
Examples
Uses an email/password login flow, a User model with a hashed-password field, and SMTP server credentials.
What it assumes
Assumes familiarity with web requests, forms, application models, and databases while laying out the login sequence step by step.
What you can do after
Apply it via Flask-Login and Flask-Bcrypt to support user login, protected endpoints, and hashed password storage.
How it connects
Connects password authentication to user models, database storage, session management, protected endpoints, cryptographic hashing, and configuration secrets.

Also explained in

Compare how 9 books explain password authentication →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Python Developer: How the pros use Python and Flask. The section links point to the parts of the book it draws on.