User Authentication
User authentication is a critical aspect of web applications, ensuring that users can securely log in, register, and access protected resources. In Flask, you can implement user authentication using tools like Flask-Login, which makes it easy to manage user sessions and protect routes.
User authentication involves verifying the identity of a user trying to access an application. The process typically includes:
- User Registration: Allowing new users to create an account by providing a username, password, and other necessary information.
- User Login: Verifying a user’s credentials (usually a username and password) to grant access to the application.
- Session Management: Keeping track of logged-in users across multiple requests and protecting routes that should only be accessible to authenticated users.
Flask-Login is a helpful extension that simplifies session management and user authentication in Flask applications.
Let’s start by creating the necessary routes for user registration and login.
Step 1: Set Up Flask-Login
First, you need to install Flask-Login:
pip install Flask-Login
Next, set up Flask-Login in your app.py:
from flask import Flask, render_template, redirect, url_for, flash, request
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
Step 2: Create the User Model
The User model needs to include fields for storing usernames, email addresses, and hashed passwords. Additionally, the model should inherit from UserMixin provided by Flask-Login:
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
email = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password, password)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
set_passwordandcheck_password: These methods handle password hashing and verification.
Step 3: Implement User Registration
Create a route to handle user registration:
@app.route('/register', methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('home'))
if request.method == 'POST':
username = request.form['username']
email = request.form['email']
password = request.form['password']
# Check if the user already exists
existing_user = User.query.filter_by(username=username).first()
if existing_user is None:
user = User(username=username, email=email)
user.set_password(password)
db.session.add(user)
db.session.commit()
flash('Registration successful!', 'success')
return redirect(url_for('login'))
else:
flash('User already exists.', 'danger')
return render_template('register.html')
Step 4: Implement User Login
Create a route to handle user login:
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
user = User.query.filter_by(username=username).first()
if user and user.check_password(password):
login_user(user)
flash('Login successful!', 'success')
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else:
flash('Login unsuccessful. Please check your credentials.', 'danger')
return render_template('login.html')
Step 5: Implement User Logout
Create a route to handle user logout:
@app.route('/logout')
def logout():
logout_user()
flash('You have been logged out.', 'info')
return redirect(url_for('login'))Once you have login functionality, you can protect certain routes so that only authenticated users can access them. Flask-Login provides a login_required decorator for this purpose.
Example: Protecting a Dashboard Route
@app.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html')
In this example, the /dashboard route is protected, meaning only logged-in users can access it. If an unauthenticated user tries to access this route, they will be redirected to the login page.
Flask-Login manages user sessions, allowing you to track the logged-in user across requests. It provides several helpful functions:
current_user: A proxy for the currently logged-in user, allowing you to access their information anywhere in your application.login_user(user): Logs in the user, starting their session.logout_user(): Logs out the user, ending their session.login_required: A decorator to protect routes that require authentication.
Example: Displaying User Information
You can use current_user to display the logged-in user’s information:
@app.route('/profile')
@login_required
def profile():
return f"Hello, {current_user.username}!"User authentication is a vital part of any web application. In Flask, you can implement authentication by setting up user registration and login functionality, securing routes with login_required, and managing user sessions with Flask-Login. This setup ensures that your application handles users securely and efficiently, providing a smooth experience for authenticated users.