Hello! Welcome to the next lesson in your journey to becoming a Full Stack AI Developer.
In our last lesson, we established the crucial theoretical foundations for secure authentication: understanding why we must hash passwords and how session-based authentication allows a web server to "remember" a user across multiple requests.
Today, we'll turn that theory into practice. The learning outcome for this lesson is to implement user registration, login, logout, and protected routes. We'll use the forms you built previously and integrate powerful Flask extensions to create a complete, secure authentication system from scratch. This is a fundamental skill for any web developer.
Let's get started.
1. Secure User Registration
Our first step is to take the data from the registration form, securely hash the password, and save the new user to our database. We'll also ensure that each user has a unique username and email.
Password Hashing and Saving Users
In the last lesson, we discussed using slow, salted hash functions. The Flask-Bcrypt extension provides a convenient way to use the robust bcrypt algorithm within Flask.
The following video from Corey Schafer's excellent Flask series will walk you through installing Flask-Bcrypt, initializing it, and using it in your registration route to securely handle passwords. It also demonstrates how to add custom validators to your form to prevent duplicate usernames and emails, which is a much more user-friendly approach than letting the database raise an error.
Python Flask Tutorial: Full-Featured Web App Part 6 - User Authentication
This video covers the entire process of building a user authentication system. We'll watch it in sections. First, let's focus on implementing a secure registration process.
Watch from the beginning (00:29) to 19:34. Pay close attention to these three key parts: Password Hashing (00:29 - 04:01): How to install and use Flask-Bcrypt to generate and check password hashes. Registration Logic (04:01 - 08:15): How to integrate password hashing into the registration route to save a new user with a hashed password. Custom Validation (10:09 - 19:34): How to add validate_username and validate_email methods to your registration form to check if a user already exists, providing a clean user experience.
To summarize the key steps for registration:
- Install and Initialize:
In your app'spip install flask-bcrypt__init__.py:from flask_bcrypt import Bcrypt bcrypt = Bcrypt(app) - Hash Password in Route: In your
registerroute, after the form validates:hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8') user = User(username=form.username.data, email=form.email.data, password=hashed_password) db.session.add(user) db.session.commit() - Add Custom Validators: In your
forms.py, inside theRegistrationFormclass:from .models import User from wtforms.validators import ValidationError def validate_username(self, username): user = User.query.filter_by(username=username.data).first() if user: raise ValidationError('That username is taken. Please choose a different one.') def validate_email(self, email): user = User.query.filter_by(email=email.data).first() if user: raise ValidationError('That email is taken. Please choose a different one.')
2. Managing User Sessions with Flask-Login
Now that users can register, we need a way to manage their sessions when they log in. This is where Flask-Login comes in. It handles all the background work of session management, such as creating session cookies and providing access to the currently logged-in user.
The setup involves three crucial steps:
- Initializing the
LoginManager. - Preparing your
Usermodel to work with Flask-Login. - Creating a
user_loaderfunction.
Let's continue with the same video to see how this is done.
Python Flask Tutorial: Full-Featured Web App Part 6 - User Authentication
This section of the video explains how to set up Flask-Login to manage user sessions.
Watch from 19:34 to 24:05. Focus on understanding the role of: The LoginManager class. The UserMixin class that you add to your User model. The @login_manager.user_loader decorated function, which tells Flask-Login how to find a specific user by their ID.
The user_loader function is the bridge between Flask-Login's session management and your user database. When a request comes in, Flask-Login reads the user ID from the session cookie and then calls your user_loader function with that ID to retrieve the actual user object. This object is then made available as current_user.
This diagram illustrates the flow after a user has logged in.
3. Implementing Login and Logout
With Flask-Login configured, we can now implement the core login and logout functionality.
Login
The login process involves:
- Finding the user in the database by their email or username.
- Verifying their password using
bcrypt.check_password_hash(). - If credentials are valid, calling
login_user()to create the session.
Logout
The logout process is even simpler: just call the logout_user() function to clear the session.
Conditional Navigation
A good user experience requires showing relevant navigation links. Logged-in users should see "Account" and "Logout," while anonymous users should see "Login" and "Register." This is easily achieved in your Jinja2 templates using current_user.is_authenticated.
Let's see this all in action.
Python Flask Tutorial: Full-Featured Web App Part 6 - User Authentication
The next sections of the video demonstrate how to build the login and logout routes and update the navigation bar.
Watch these two segments: Login Route (24:05 - 28:26): See how to query the user, check the password, and use login_user(). Logout and Navigation (31:27 - 35:08): Learn how to create the logout route with logout_user() and use current_user.is_authenticated in the template to display the correct links.
4. Protected Routes and Final Touches
The primary purpose of authentication is to restrict access to certain parts of your application. Flask-Login makes this incredibly simple with the @login_required decorator.
We also want to improve the user experience by redirecting users back to the page they were trying to access before they were prompted to log in.
Python Flask Tutorial: Full-Featured Web App Part 6 - User Authentication
Let's finish by implementing route protection and a few final enhancements.
Watch from 29:32 to the end of the video (46:21). You will learn: Preventing Access (29:32 - 31:27): How to stop already logged-in users from visiting the login/register pages. Route Protection (35:08 - 40:01): How to use the @login_required decorator and configure the login_view. Redirects and Messaging (40:01 - 46:21): How to handle the next query parameter for a smooth redirect after login and how to customize flashed messages.
To make a route require authentication, you do two things:
- Tell Flask-Login where your login page is in your
__init__.py:login_manager.login_view = 'auth.login' # 'auth.login' is the endpoint name - Add the decorator to any route you want to protect:
from flask_login import login_required @app.route('/account') @login_required def account(): # This code will only run if the user is logged in return render_template('account.html')
This flowchart provides a high-level overview of the complete authentication system you've just built.
Conclusion
Congratulations! You have now implemented a complete and secure user authentication system in Flask. This is a major milestone and a foundational component of almost every web application you will build.
Key Takeaways:
- Registration: Use
Flask-Bcrypt'sgenerate_password_hash()to securely store passwords and implement custom form validators to check for unique user details. - Flask-Login Setup: Configure
Flask-Loginby initializingLoginManager, addingUserMixinto yourUsermodel, and creating a@login_manager.user_loadercallback. - Login/Logout: Use
login_user()to create a session andlogout_user()to destroy it. - Access Control: Use the
@login_requireddecorator to protect routes andcurrent_user.is_authenticatedin templates to control what the user sees. - User Experience: Improve flow by redirecting users to their intended page after login using the
nextparameter.
In our next lesson, we'll shift gears to another core component of modern web development: building RESTful APIs. You'll learn the principles behind APIs and how to build your first endpoints using Flask, which will eventually allow your AI models to communicate with other services and front-end applications.