Authenticating Users with Login Functionality

Authenticating Users with Login Functionality

Welcome to the lesson on implementing user login functionality in your Flask ToDo App. In previous lessons, we've set up the authentication middleware and added secure user registration. Building on these foundations, we'll now focus on allowing registered users to log in. This step is vital as it ensures a secure and personalized experience for users interacting with the app. You will learn how to authenticate users using their credentials and maintain their session for secure access to the app's features.

Checking Hashed Password

You may recall from our user registration lesson that we set up a User model to store user data securely. Now, let's create the check_password method, which will be crucial for verifying user credentials during login. This method will compare the hash of a provided password with the stored password hash in the database to ensure validity.

Here's how you can implement it in app/models/user.py:

from werkzeug.security import check_password_hash

class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(150), unique=True, nullable=False)
    password_hash = db.Column(db.String(200), nullable=False)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)
    
    # Method to compare given password with the hashed one
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

The check_password method is designed to validate user-entered passwords by comparing them against the hashed password stored within the user model.

  • Password Validation: It uses check_password_hash to perform a secure comparison, ensuring that the hashed value of the provided password matches the one stored in the database.
  • Return Value: The method returns True if the passwords match, allowing successful authentication, or False if they do not match, indicating an authentication failure.

Implementing User Login Service

Now, let's dive into the login functionality. We'll use the UserService to also handle the logic of authenticating a user with their credentials.

Here's the relevant function in app/services/user_service.py:

from models.user import User, db

class UserService:
 
    # Register method...   

    # Login method
    @staticmethod
    def login(username, password):
        # Retrieve user instance using its username
        user = User.query.filter_by(username=username).first()
        # Use the check_password method to compare the passwords
        if user and user.check_password(password):
            # Return the user object if login is successful
            return user
        # Return None if login fails due to invalid credentials
        return None

This function contains the logic needed for user authentication:

  • User Fetching: We fetch the user based on the username.
  • Password Checking: If the user exists, we verify their password using the check_password method.
  • Return Value: If both checks pass, the user object is returned. Otherwise, None is returned to indicate unsuccessful login.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal