An open API service indexing awesome lists of open source software.

https://github.com/hu55ain3laa/fastauth

A comprehensive authentication and authorization library for FastAPI applications with JWT-based authentication, role-based authorization, and SQLModel integration.
https://github.com/hu55ain3laa/fastauth

authentication backend fastapi

Last synced: 6 months ago
JSON representation

A comprehensive authentication and authorization library for FastAPI applications with JWT-based authentication, role-based authorization, and SQLModel integration.

Awesome Lists containing this project

README

          


FastAuth Logo

A comprehensive authentication and authorization library for FastAPI applications
with JWT-based authentication, role-based authorization, and SQLModel integration.



PyPI version
License: MIT

📖 Full Documentation Available Here


## 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](https://hu55ain3laa.github.io/fastauth/)**.

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Authentication](#authentication)
- [Login and Token Management](#login-and-token-management)
- [Protected Routes](#protected-routes)
- [Cookie-Based Authentication](#cookie-based-authentication)
- [Database Initialization](#database-initialization)
- [CLI Initialization](#cli-initialization-new-in-v030)
- [Programmatic Initialization](#programmatic-initialization)
- [Role-Based Authorization](#role-based-authorization)
- [Standard Roles](#standard-roles)
- [Role Requirements](#role-requirements)
- [Role Management API](#role-management-api)
- [API Reference](#api-reference)
- [Authentication Endpoints](#authentication-endpoints)
- [Role Management Endpoints](#role-management-endpoints)
- [Error Handling](#error-handling)
- [Custom Exceptions](#custom-exceptions)
- [Standardized Error Responses](#standardized-error-responses)
- [Advanced Usage](#advanced-usage)
- [Custom User Models](#custom-user-models)
- [Custom Authentication Logic](#custom-authentication-logic)
- [Security Best Practices](#security-best-practices)
- [Project Structure](#project-structure)
- [License](#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
- **Comprehensive error handling** with standardized error responses (new in v0.3.4)
- **Password hashing** with bcrypt
- **Modular architecture** for better code organization and extensibility

## Installation

```bash
pip install fastauth_iq
```

Or install from source:

```bash
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:

```python
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

```python
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"])

# Set up standardized error handling (new in v0.3.4)
auth.setup_exception_handlers(app)
```

### 3. Protect Your Routes

```python
# 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:

1. User submits credentials to `/token` endpoint
2. Server validates credentials and returns access + refresh tokens
3. Client uses access token for API requests (via header or cookie)
4. 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:

```python
# 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:

```python
# Enable cookie-based auth when creating FastAuth instance
auth = FastAuth(
# ... other parameters ...
use_cookie=True
)
```

With cookie-based auth enabled:
- The `/token` endpoint 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.

```bash
# 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:**
```bash
# 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:**
```python
# 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:**
```python
# 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:

```python
# 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:

```python
# 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 privileges
- `admin`: Administrator with management privileges
- `moderator`: User with content moderation privileges
- `premium`: Premium tier user
- `verified`: Verified user
- `user`: Standard user with basic privileges

### Role Requirements

FastAuth provides flexible role-based access control:

```python
# 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:

```python
# 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

FastAuth provides the following authentication endpoints:

- `POST /token` - Login and get access + refresh tokens
- `POST /token/refresh` - Use refresh token to get a new access token
- `POST /users` - Register a new user
- `GET /users/me` - Get current user information

### Role Management Endpoints

FastAuth provides these role management endpoints (all under `/roles` by default):

- `POST /roles/` - Create a new role (admin only)
- `GET /roles/` - Get all roles (authenticated users)
- `GET /roles/{role_id}` - Get a specific role (authenticated users)
- `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 role to user (admin only)
- `DELETE /roles/assign/{user_id}/{role_id}` - Remove role from user (admin only)

## Error Handling

FastAuth provides a comprehensive error handling system that delivers consistent, informative error responses across all endpoints (new in v0.3.4).

### Custom Exceptions

The library includes specialized exception classes for different error scenarios:

```python
from fastauth import (
CredentialsException, # Authentication failures
TokenException, # Token verification issues
RefreshTokenException, # Refresh token problems
InactiveUserException, # User account is disabled
UserNotFoundException, # User doesn't exist
UserExistsException, # Username already taken
RoleNotFoundException, # Role doesn't exist
RoleExistsException, # Role already exists
PermissionDeniedException # Insufficient permissions
)
```

### Standardized Error Responses

All FastAuth exceptions return a consistent JSON structure:

```json
{
"error": {
"code": "FASTAUTH_ERROR_CODE",
"message": "Human-readable error description",
"status_code": 401 // HTTP status code
}
}
```

Enabling error handling is simple:

```python
app = FastAPI()
auth = FastAuth(...)

# Register exception handlers with your FastAPI app
auth.setup_exception_handlers(app)
```

This makes debugging easier and allows clients to handle errors in a consistent way. Each exception type has its own specific error code, making it straightforward to identify and respond to different error scenarios.

## Advanced Usage

### Custom User Models

You can use a custom user model with FastAuth:

```python
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:

```python
# 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:

1. **Deploy your FastAPI app with HTTPS** in production environments
2. **Use a strong secret key** for FastAuth and store it securely (e.g., environment variables)
3. **Configure appropriate token expiration times** based on your security requirements
4. **Keep secure cookie settings** when using cookie-based authentication (FastAuth sets `httpOnly=True` which prevents JavaScript from accessing cookies, protecting against XSS attacks)
5. **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