A comprehensive authentication and authorization library for FastAPI with JWT, cookie support, role-based access control, and automatic database initialization
Project description
A comprehensive authentication and authorization library for FastAPI applications
with JWT-based authentication, role-based authorization, and SQLModel integration.
Documentation
This README provides a quick overview of FastAuth. For a more complete, interactive documentation with live examples and responsive design, visit our GitHub Pages Documentation.
Table of Contents
- Features
- Installation
- Quick Start
- Authentication
- Database Initialization
- Role-Based Authorization
- API Reference
- Advanced Usage
- Security Best Practices
- Project Structure
- License
Features
- OAuth2 and JWT authentication built-in
- Role-based authorization system
- Cookie-based authentication option
- Token refresh mechanism for extended sessions
- SQLModel integration for easy database operations
- CLI utilities for database initialization and management (new in v0.3.0)
- Ready-to-use authentication routes with minimal setup
- Password hashing with bcrypt
- Modular architecture for better code organization and extensibility
Installation
pip install fastauth_iq
Or install from source:
git clone https://github.com/hu55ain3laa/fastauth.git
cd fastauth
pip install -e .
Quick Start
1. Create a User Model
FastAuth works with SQLModel's user model. You can use the built-in User model or create your own:
from sqlmodel import SQLModel, Field
class User(SQLModel, table=True):
id: int = Field(primary_key=True)
username: str = Field(unique=True)
email: str = Field(unique=True)
hashed_password: str
disabled: bool = Field(default=False)
2. Initialize FastAuth in Your Application
from fastapi import FastAPI, Depends
from sqlmodel import create_engine, Session, SQLModel
from fastauth import FastAuth, User
# Create FastAPI app
app = FastAPI()
# Setup database
engine = create_engine("sqlite:///./app.db")
# Session dependency
def get_session():
with Session(engine) as session:
yield session
# Initialize FastAuth with your configuration
auth = FastAuth(
secret_key="your-secure-secret-key", # Use strong secret in production
algorithm="HS256",
user_model=User,
engine=engine,
use_cookie=True, # Enable cookie-based auth (optional)
token_url="/token",
access_token_expires_in=30, # minutes
refresh_token_expires_in=7 # days
)
# Initialize database (choose ONE of these approaches):
# Option 1: Using the CLI tool before starting the application (new in v0.3.0)
# fastauth app.py # Auto-detect settings from your app file
# # Or use explicit parameters
# fastauth --db-url="sqlite:///./app.db" --secret-key="your-secret-key"
#
# Option 2: Initializing during application startup
INIT_DB_ON_STARTUP = True # Set to False to disable
@app.on_event("startup")
def on_startup():
if INIT_DB_ON_STARTUP:
auth.initialize_db(
create_tables=True, # Create database tables
init_roles=True, # Initialize standard roles
create_admin=True, # Create superadmin if needed
admin_username="superadmin", # Default username
admin_password="admin123" # Default password
)
# Add all authentication routes automatically
auth_router = auth.get_auth_router(get_session)
app.include_router(auth_router, tags=["authentication"])
# Add role management routes (new in v0.2.2)
role_router = auth.get_role_router()
app.include_router(role_router, tags=["roles"])
3. Protect Your Routes
# Require authentication only
@app.get("/protected")
def protected_route(current_user = Depends(auth.get_current_active_user_dependency())):
return {"message": f"Hello, {current_user.username}!"}
# Require specific roles (any of the listed roles)
@app.get("/admin-or-moderator")
def admin_or_mod_route(current_user = Depends(auth.require_roles(["admin", "moderator"]))):
return {"message": f"Hello privileged user, {current_user.username}!"}
# Require all listed roles
@app.get("/admin-and-verified")
def admin_and_verified_route(current_user = Depends(auth.require_all_roles(["admin", "verified"]))):
return {"message": f"Hello admin with verification, {current_user.username}!"}
# Shortcut for admin-only routes
@app.get("/admin-only")
def admin_only_route(current_user = Depends(auth.is_admin())):
return {"message": f"Hello admin, {current_user.username}!"}
Authentication
Login and Token Management
FastAuth implements JWT-based authentication with both access tokens and refresh tokens:
- Access tokens are short-lived (default: 30 minutes) and used for regular API access
- Refresh tokens are long-lived (default: 7 days) and used to obtain new access tokens
User authentication flow:
- User submits credentials to
/tokenendpoint - Server validates credentials and returns access + refresh tokens
- Client uses access token for API requests (via header or cookie)
- When access token expires, client uses refresh token to get a new one from
/token/refresh
Protected Routes
To protect a route, use FastAuth's dependencies:
# Basic authentication - any valid user
@app.get("/protected")
def protected_route(user = Depends(auth.get_current_active_user_dependency())):
return {"message": "Protected content", "user": user.username}
Cookie-Based Authentication
FastAuth supports both header-based and cookie-based authentication:
# Enable cookie-based auth when creating FastAuth instance
auth = FastAuth(
# ... other parameters ...
use_cookie=True
)
With cookie-based auth enabled:
- The
/tokenendpoint will set HTTP-only cookies with the tokens - Protected routes will check for tokens in cookies if not found in headers
- The cookie approach is more secure for browser-based applications
Database Initialization
CLI Initialization (new in v0.3.0)
FastAuth provides a convenient CLI tool for database initialization, which is ideal for production environments.
# Just provide your app file - FastAuth will extract settings automatically
fastauth example.py
# Or use the traditional approach
fastauth --db-url="sqlite:///./app.db" --secret-key="your-secret-key"
# Customize the superadmin credentials
fastauth example.py --username="admin" --password="secure_password"
# Run specific initialization steps
fastauth example.py --init-db --init-roles --create-superadmin
The CLI tool will prompt for credentials if not provided, with defaults:
- Username:
superadmin - Password:
admin123
Setting up your Application File for Auto-Detection
When using the fastauth example.py syntax, FastAuth auto-detects database URL and secret key settings from multiple sources (new in v0.3.3):
1. Environment Variables:
# Set these environment variables before running FastAuth CLI
export DATABASE_URL="sqlite:///./app.db"
export SECRET_KEY="your-secret-key-here"
2. .env Files:
Create a .env file in your project directory:
DATABASE_URL=sqlite:///./app.db
SECRET_KEY=your-secret-key-here
3. Python Module Variables:
# Database URL - any of these formats will be detected
DATABASE_URL = "sqlite:///./app.db"
database_url = "sqlite:///./app.db"
db_url = "sqlite:///./app.db"
engine = create_engine("sqlite:///./app.db")
# Secret Key - any of these formats will be detected
SECRET_KEY = "your-secret-key-here"
secret_key = "your-secret-key-here"
4. Imported Modules and Engine Objects:
# FastAuth will detect imported engine objects
from database import engine # Where database.py contains an engine definition
# And imported configuration variables
from config import DATABASE_URL, SECRET_KEY
FastAuth will search for these variables in:
- The specified app file
- Common configuration files (config.py, settings.py, db.py, etc.)
- Imported modules
If FastAuth cannot detect your settings, you can still provide them with the --db-url and --secret-key flags.
Programmatic Initialization
You can also initialize the database programmatically during application startup, which is simpler for development environments:
# Initialize during application startup
@app.on_event("startup")
def on_startup():
auth.initialize_db(
create_tables=True, # Create database tables
init_roles=True, # Initialize standard roles
create_admin=True, # Create superadmin if needed
admin_username="superadmin", # Default username
admin_password="admin123" # Default password
)
You can also create a superadmin user programmatically at any time:
# Create a superadmin user with default credentials
auth.create_superadmin()
# Or with custom credentials
auth.create_superadmin(username="admin", password="secure_password")
Role-Based Authorization
FastAuth includes a robust role-based authorization system:
Standard Roles
The initialization creates these standard roles:
superadmin: Super administrator with all privilegesadmin: Administrator with management privilegesmoderator: User with content moderation privilegespremium: Premium tier userverified: Verified useruser: Standard user with basic privileges
Role Requirements
FastAuth provides flexible role-based access control:
# Require any of these roles (OR condition)
@app.get("/admin-or-moderator")
def admin_route(user = Depends(auth.require_roles(["admin", "moderator"]))):
return {"message": "Admin or moderator area"}
# Require all of these roles (AND condition)
@app.get("/premium-and-verified")
def premium_verified_route(user = Depends(auth.require_all_roles(["premium", "verified"]))):
return {"message": "Premium and verified area"}
# Shortcut for admin-only routes
@app.get("/admin-only")
def admin_only(user = Depends(auth.is_admin())):
return {"message": "Admin only area"}
Role Management API
FastAuth provides a complete API for role management:
# Get the role router and include it in your app
role_router = auth.get_role_router()
app.include_router(role_router, tags=["roles"])
This adds these role management endpoints:
- POST /roles/ - Create a new role (admin only)
- GET /roles/ - Get all roles
- GET /roles/{role_id} - Get a role by ID
- PUT /roles/{role_id} - Update a role (admin only)
- DELETE /roles/{role_id} - Delete a role (admin only)
- POST /roles/assign/{user_id}/{role_id} - Assign a role to a user (admin only)
- DELETE /roles/assign/{user_id}/{role_id} - Remove a role from a user (admin only)
- GET /roles/user/{user_id} - Get all roles for a user
API Reference
Authentication Endpoints
The auth_router adds these endpoints:
- POST /token - Get access and refresh tokens with username/password
- POST /token/refresh - Get a new access token using a refresh token
- POST /users - Register a new user
- GET /users/me - Get the current authenticated user's information
Role Management Endpoints
The role_router adds these endpoints:
- GET /roles - List all roles
- POST /roles - Create a new role (admin only)
- GET /roles/{role_id} - Get a role by ID
- PUT /roles/{role_id} - Update a role (admin only)
- DELETE /roles/{role_id} - Delete a role (admin only)
- POST /roles/assign/{user_id}/{role_id} - Assign a role to a user (admin only)
- DELETE /roles/assign/{user_id}/{role_id} - Remove a role from a user (admin only)
- GET /roles/user/{user_id} - Get all roles for a user
Advanced Usage
Custom User Models
You can use a custom user model with FastAuth:
class CustomUser(SQLModel, table=True):
id: int = Field(primary_key=True)
username: str = Field(unique=True)
email: str = Field(unique=True)
hashed_password: str
disabled: bool = Field(default=False)
# Additional fields...
first_name: str = Field(default="")
last_name: str = Field(default="")
# Pass your custom model to FastAuth
auth = FastAuth(
# ... other parameters ...
user_model=CustomUser
)
Custom Authentication Logic
You can customize the authentication logic:
# Custom authentication routes
@app.post("/custom-login")
async def custom_login(
username: str,
password: str,
session: Session = Depends(get_session)
):
user = auth.authenticate_user(username, password)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
access_token = auth.create_access_token(data={"sub": user.username})
return {"access_token": access_token, "token_type": "bearer"}
Security Best Practices
When using FastAuth in your applications, consider these security recommendations:
- Deploy your FastAPI app with HTTPS in production environments
- Use a strong secret key for FastAuth and store it securely (e.g., environment variables)
- Configure appropriate token expiration times based on your security requirements
- Keep secure cookie settings when using cookie-based authentication (FastAuth sets
httpOnly=Truewhich prevents JavaScript from accessing cookies, protecting against XSS attacks) - Consider implementing rate limiting on your authentication endpoints to prevent brute force attacks
Project Structure
FastAuth follows a modular architecture for better maintainability:
fastauth/
├── core/ # Core functionality
│ ├── auth.py # The main FastAuth class
│ ├── password.py # Password management
│ └── tokens.py # Token generation and validation
├── models/ # Data models
│ ├── user.py # User models and schemas
│ ├── role.py # Role models for authorization
│ └── tokens.py # Token data models
├── routers/ # Route handlers for auth and roles
├── dependencies/ # FastAPI dependencies for auth and roles
└── utils/ # Utility functions and helpers
This modular structure makes it easier to:
- Understand the codebase
- Extend or customize functionality
- Test individual components
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastauth_iq-0.3.3.tar.gz.
File metadata
- Download URL: fastauth_iq-0.3.3.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39ac0ebb487f07d2dfa3748577472ddd9724551cb2606a299442623cb008c75f
|
|
| MD5 |
7e165ab7792b122be944a011809b397d
|
|
| BLAKE2b-256 |
132736e170db3ea622eb3e04efe77710174f8170a296af74a123cb95b5245433
|
File details
Details for the file fastauth_iq-0.3.3-py3-none-any.whl.
File metadata
- Download URL: fastauth_iq-0.3.3-py3-none-any.whl
- Upload date:
- Size: 27.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
055ae047d4ffa393418406da6737dccec031448ef9816dd64d34ba296bb51a25
|
|
| MD5 |
a632a8c26286ee0de2fad115ffc4d200
|
|
| BLAKE2b-256 |
7f4e4df2c78ba5b1cdf7bb3368dda63838488958ca44a3f48aeb9dae11832618
|