Flask Extensions Recommended: Flask-SQLAlchemy and User Authentication

Why Flask Extensions Are Needed?

Flask is a lightweight Python Web framework that provides only the most basic functionalities, such as routing and template rendering. When more complex features are required (e.g., database connection, user authentication, form validation), we rely on extensions. These extensions are developed by the community, encapsulating common functionalities, allowing us to build applications faster without writing code from scratch.

Flask-SQLAlchemy: Simplifying Database Operations

Data storage is a core feature of web applications. Flask-SQLAlchemy is an extension that integrates SQLAlchemy (a powerful ORM library) into Flask, enabling database operations using Python objects instead of writing raw SQL statements.

Installation

pip install flask-sqlalchemy

Basic Configuration

Initialize SQLAlchemy and configure the database in a Flask application:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# Configure database URI (using SQLite for development/testing)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
# Disable SQLAlchemy's modification tracking to reduce resource consumption
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Initialize SQLAlchemy instance
db = SQLAlchemy(app)

Define Data Models

For user authentication, create a User model to store user information:

class User(db.Model):
    __tablename__ = 'users'  # Table name
    id = db.Column(db.Integer, primary_key=True)  # Primary key
    username = db.Column(db.String(80), unique=True, nullable=False)  # Username
    password_hash = db.Column(db.String(128), nullable=False)  # Hashed password

Database Operations

  • Create Tables: Execute db.create_all() to create all tables (run within with app.app_context()):
  with app.app_context():
      db.create_all()  # Create database tables
  • Add a User:
  new_user = User(username='testuser', password_hash='hashed_password')
  db.session.add(new_user)  # Add to session
  db.session.commit()  # Commit transaction to save to database
  • Query a User:
  user = User.query.filter_by(username='testuser').first()  # Query user by username
  if user:
      print(f"Found user: {user.username}")
  • Update/Delete a User:
  # Update
  user = User.query.get(1)
  user.username = 'newusername'
  db.session.commit()

  # Delete
  user = User.query.get(1)
  db.session.delete(user)
  db.session.commit()

User Authentication: Flask-Login and Secure Storage

The core of user authentication is verifying identity and maintaining login status. Flask-Login is an extension that handles user sessions and login state management, working with database-stored user information to quickly implement login/logout functionality.

Install Flask-Login

pip install flask-login

Configure Flask-Login

Initialize LoginManager and set up the user loader function:

from flask_login import LoginManager, login_user, login_required, logout_user, current_user

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'  # Redirect to login page if not authenticated

# User loader function: query user by ID (required)
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))  # Query user by ID

Secure Password Storage

Never store passwords in plain text! Use Werkzeug’s generate_password_hash and check_password_hash for encryption:

from werkzeug.security import generate_password_hash, check_password_hash

class User(db.Model):
    # Add password hashing methods
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)  # Hash password
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)  # Verify password

Login/Logout Functionality

  • Login View: Verify user credentials and maintain session:
  @app.route('/login', methods=['GET', 'POST'])
  def login():
      if request.method == 'POST':
          username = request.form.get('username')
          password = request.form.get('password')
          user = User.query.filter_by(username=username).first()

          if user and user.check_password(password):
              login_user(user)  # Maintain session after successful login
              return redirect(url_for('dashboard'))
          else:
              return "Invalid username or password"

      # GET request: Display login form
      return '''
          <form method="POST">
              <input type="text" name="username" placeholder="Username"><br>
              <input type="password" name="password" placeholder="Password"><br>
              <button type="submit">Login</button>
          </form>
      '''
  • Logout View:
  @app.route('/logout')
  @login_required  # Only accessible to authenticated users
  def logout():
      logout_user()  # Clear session and log out
      return redirect(url_for('index'))

Protect Routes

Use the @login_required decorator to protect pages requiring authentication:

@app.route('/dashboard')
@login_required
def dashboard():
    return f"Welcome, {current_user.username}!"  # current_user is the logged-in user

Summary

By using Flask-SQLAlchemy and Flask-Login, we can quickly build a web application with database and user authentication:

  • Flask-SQLAlchemy: Manipulate databases via Python objects (no SQL writing), simplifying CRUD operations.
  • Flask-Login: Handle user sessions and login status, paired with password encryption for secure authentication.

Beginners can master basic installation, configuration, and core APIs (e.g., db.create_all(), login_user(), logout_user()) to rapidly build user systems. For production, consider HTTPS, CSRF protection, and additional extensions like Flask-WTF (form validation) or Flask-Security to enhance the application.

Xiaoye