Production-ready authentication for FastAPI applications
Project description
FastAuth
Production-ready authentication for FastAPI applications
FastAuth is a flexible, database-agnostic authentication library for FastAPI that provides secure user authentication, session management, and authorization out of the box.
Features
- Complete Authentication Flow - Registration, login, logout, and token refresh
- Session Management - Track and manage active user sessions across devices
- Role-Based Access Control (RBAC) - Fine-grained authorization with roles and permissions
- Email Verification - Secure email verification with expiring tokens
- Password Reset - Self-service password reset via email
- Refresh Tokens - Long-lived refresh tokens with rotation support
- Rate Limiting - Built-in rate limiting for authentication endpoints
- Database Agnostic - Adapter pattern supports any database (SQLAlchemy included)
- Type Safe - Full type hints and Pydantic validation
- Production Ready - Secure defaults, comprehensive tests, and CI/CD pipeline
Installation
From PyPI (Coming Soon)
pip install sreekarnv-fastauth
From Source
git clone https://github.com/sreekarnv/fastauth.git
cd fastauth
pip install .
With Poetry
poetry add fastauth
Quick Start
Here's a complete authentication system in under 5 minutes:
1. Install FastAuth
pip install sreekarnv-fastauth
2. Create Your Application
from fastapi import FastAPI, Depends
from sqlmodel import Session, SQLModel, create_engine
from fastauth import auth_router, sessions_router
from fastauth.api import dependencies
from fastauth.adapters.sqlalchemy.models import User
# Database setup
DATABASE_URL = "sqlite:///./app.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
def init_db():
SQLModel.metadata.create_all(engine)
def get_session():
with Session(engine) as session:
yield session
# Create FastAPI app
app = FastAPI(title="My App")
# Initialize database
init_db()
# Include FastAuth routers
app.include_router(auth_router)
app.include_router(sessions_router)
# Override session dependency
app.dependency_overrides[dependencies.get_session] = get_session
# Protected route example
from fastauth.api.dependencies import get_current_user
@app.get("/protected")
def protected_route(current_user: User = Depends(get_current_user)):
return {"message": f"Hello {current_user.email}!"}
3. Configure Environment Variables
Create a .env file:
# JWT Settings
JWT_SECRET_KEY=your-secret-key-here-change-in-production
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# Email Settings (optional - uses console by default)
EMAIL_PROVIDER=console # or smtp, sendgrid, resend, ses
REQUIRE_EMAIL_VERIFICATION=false # Set to true in production
4. Run Your Application
uvicorn main:app --reload
5. Try It Out
Visit http://localhost:8000/docs to see the auto-generated API documentation and try:
Register a user:
curl -X POST "http://localhost:8000/auth/register" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "securepassword123"}'
Login:
curl -X POST "http://localhost:8000/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "securepassword123"}'
Access protected route:
curl -X GET "http://localhost:8000/protected" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
That's it! You now have a working authentication system.
API Endpoints
FastAuth automatically adds these endpoints to your application:
Authentication
| Method | Endpoint | Description |
|---|---|---|
POST |
/auth/register |
Register a new user |
POST |
/auth/login |
Login with email and password |
POST |
/auth/logout |
Logout and revoke refresh token |
POST |
/auth/refresh |
Get new access token using refresh token |
POST |
/auth/password-reset/request |
Request password reset email |
POST |
/auth/password-reset/confirm |
Reset password with token |
POST |
/auth/email-verification/request |
Request email verification |
POST |
/auth/email-verification/confirm |
Verify email with token |
POST |
/auth/email-verification/resend |
Resend verification email |
Session Management
| Method | Endpoint | Description |
|---|---|---|
GET |
/sessions |
List all active sessions for authenticated user |
DELETE |
/sessions/all |
Delete all user sessions (logout from all devices) |
DELETE |
/sessions/{session_id} |
Delete a specific session |
Architecture
FastAuth uses a clean, layered architecture:
┌─────────────────────────────────────┐
│ FastAPI Routes │ ← Your application
├─────────────────────────────────────┤
│ FastAuth API Layer │ ← HTTP handlers
├─────────────────────────────────────┤
│ Core Business Logic │ ← Database-agnostic
├─────────────────────────────────────┤
│ Adapter Interface │ ← Abstract base classes
├─────────────────────────────────────┤
│ Adapter Implementation │ ← SQLAlchemy, MongoDB, etc.
│ (SQLAlchemy, MongoDB, etc.) │
└─────────────────────────────────────┘
Key Principles:
- Database Agnostic Core - Business logic has no database dependencies
- Adapter Pattern - Swap databases by implementing the adapter interface
- Dependency Injection - Easy to customize and test
- Type Safety - Full type hints throughout
Configuration
FastAuth can be configured via environment variables or the Settings class:
Environment Variables
# JWT Configuration
JWT_SECRET_KEY=your-secret-key-min-32-chars
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# Email Configuration
EMAIL_PROVIDER=console # console, smtp, sendgrid, resend, ses
REQUIRE_EMAIL_VERIFICATION=false
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM_EMAIL=noreply@yourapp.com
# Rate Limiting
RATE_LIMIT_ENABLED=true
LOGIN_RATE_LIMIT=5 # attempts per window
LOGIN_RATE_WINDOW=300 # seconds (5 minutes)
Programmatic Configuration
from fastauth import Settings
settings = Settings(
jwt_secret_key="your-secret-key",
access_token_expire_minutes=60,
require_email_verification=True
)
Usage Examples
Protecting Routes
from fastapi import Depends
from fastauth.api.dependencies import get_current_user
from fastauth.adapters.sqlalchemy.models import User
@app.get("/profile")
def get_profile(current_user: User = Depends(get_current_user)):
return {
"email": current_user.email,
"verified": current_user.is_verified,
"created_at": current_user.created_at
}
Custom User Model
from sqlmodel import Field
from fastauth.adapters.sqlalchemy.models import User as BaseUser
class User(BaseUser, table=True):
__tablename__ = "users"
# Add custom fields
first_name: str | None = None
last_name: str | None = None
company: str | None = None
Role-Based Access Control (RBAC)
Protect routes with roles and permissions for fine-grained authorization:
Creating Roles and Permissions
from fastauth import create_role, create_permission, assign_permission_to_role, assign_role
from fastauth.adapters.sqlalchemy.roles import SQLAlchemyRoleAdapter
# Create roles
admin_role = create_role(roles=role_adapter, name="admin", description="Administrator")
moderator_role = create_role(roles=role_adapter, name="moderator", description="Moderator")
user_role = create_role(roles=role_adapter, name="user", description="Regular user")
# Create permissions
read_users = create_permission(roles=role_adapter, name="read:users")
write_users = create_permission(roles=role_adapter, name="write:users")
delete_users = create_permission(roles=role_adapter, name="delete:users")
# Assign permissions to roles
assign_permission_to_role(roles=role_adapter, role_name="admin", permission_name="read:users")
assign_permission_to_role(roles=role_adapter, role_name="admin", permission_name="write:users")
assign_permission_to_role(roles=role_adapter, role_name="admin", permission_name="delete:users")
# Assign role to user
assign_role(roles=role_adapter, user_id=user.id, role_name="admin")
Protecting Routes by Role
from fastapi import Depends
from fastauth.api.dependencies import require_role
@app.get("/admin/dashboard", dependencies=[Depends(require_role("admin"))])
def admin_dashboard():
return {"message": "Admin access granted"}
@app.get("/moderator/panel", dependencies=[Depends(require_role("moderator"))])
def moderator_panel():
return {"message": "Moderator access granted"}
Protecting Routes by Permission
from fastapi import Depends
from fastauth.api.dependencies import require_permission
@app.get("/users", dependencies=[Depends(require_permission("read:users"))])
def list_users():
return {"users": [...]}
@app.delete("/users/{id}", dependencies=[Depends(require_permission("delete:users"))])
def delete_user(id: str):
return {"message": "User deleted"}
@app.post("/users", dependencies=[Depends(require_permission("write:users"))])
def create_user(user_data: dict):
return {"message": "User created"}
Checking Permissions Programmatically
from fastauth import check_permission
# Check if user has specific permission
has_access = check_permission(
roles=role_adapter,
user_id=user.id,
permission_name="delete:users"
)
if has_access:
# Perform action
pass
Session Management
Track and manage user sessions across multiple devices for enhanced security:
Viewing Active Sessions
Sessions are automatically created when users log in or register. Users can view all their active sessions:
from fastapi import Depends
from fastauth.api.dependencies import get_current_user
from fastauth.adapters.sqlalchemy.models import User
@app.get("/my-sessions")
def get_my_sessions(current_user: User = Depends(get_current_user)):
return {"user_id": current_user.id}
Session Information
Each session contains:
- Device - Device name or identifier
- IP Address - Client IP address
- User Agent - Browser/client information
- Last Active - Last activity timestamp
- Created At - Session creation time
Revoking Sessions
Users can revoke individual sessions (e.g., logout from a specific device):
curl -X DELETE "http://localhost:8000/sessions/{session_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Or logout from all devices at once:
curl -X DELETE "http://localhost:8000/sessions/all" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Programmatic Session Management
from fastauth import create_session, get_user_sessions, delete_session
from fastauth.adapters.sqlalchemy.sessions import SQLAlchemySessionAdapter
session = create_session(
sessions=session_adapter,
users=user_adapter,
user_id=user.id,
device="iPhone 13",
ip_address="192.168.1.1",
user_agent="Mozilla/5.0"
)
user_sessions = get_user_sessions(
sessions=session_adapter,
user_id=user.id
)
delete_session(
sessions=session_adapter,
session_id=session.id,
user_id=user.id
)
Session Cleanup
Automatically cleanup inactive sessions:
from fastauth import cleanup_inactive_sessions
cleanup_inactive_sessions(
sessions=session_adapter,
inactive_days=30
)
This can be scheduled as a background task:
from fastapi import FastAPI
from apscheduler.schedulers.background import BackgroundScheduler
app = FastAPI()
def cleanup_old_sessions():
cleanup_inactive_sessions(sessions=session_adapter, inactive_days=30)
scheduler = BackgroundScheduler()
scheduler.add_job(cleanup_old_sessions, 'interval', days=1)
scheduler.start()
Using Different Databases
FastAuth works with any database through adapters:
SQLAlchemy (built-in):
from fastauth.adapters.sqlalchemy import SQLAlchemyUserAdapter
MongoDB (install fastauth[mongodb]):
from fastauth.adapters.mongodb import MongoDBUserAdapter
Custom adapter:
from fastauth.adapters.base import UserAdapter
class MyCustomAdapter(UserAdapter):
def create_user(self, email: str, hashed_password: str):
# Your implementation
pass
Advanced Features
Email Verification
Enable email verification for new signups:
# .env
REQUIRE_EMAIL_VERIFICATION=true
EMAIL_PROVIDER=smtp # or sendgrid, resend, ses
Users must verify their email before logging in.
Password Reset
Users can reset their password via email:
- Request reset:
POST /auth/password-reset/request - Receive email with reset link
- Submit new password:
POST /auth/password-reset/confirm
Rate Limiting
Built-in rate limiting protects against brute force attacks:
- Login attempts: 5 per 5 minutes (configurable)
- Registration: 3 per 10 minutes
- Email verification: 3 per 10 minutes
Refresh Token Rotation
Refresh tokens are automatically rotated on use for enhanced security:
# Old refresh token is invalidated
# New refresh token is issued
response = await refresh_tokens(refresh_token)
Examples
Check out the examples directory for complete applications:
- Basic Example - Simple FastAPI app with FastAuth
Development
Setup Development Environment
# Clone repository
git clone https://github.com/sreekarnv/fastauth.git
cd fastauth
# Install dependencies
poetry install
# Install pre-commit hooks
poetry run pre-commit install
# Run tests
poetry run pytest
# Run linting
poetry run black .
poetry run ruff check .
Running Tests
# All tests
poetry run pytest
# With coverage
poetry run pytest --cov=fastauth --cov-report=html
# Specific test file
poetry run pytest tests/core/test_users.py
# Verbose output
poetry run pytest -v
Project Structure
fastauth/
├── fastauth/ # Main package
│ ├── core/ # Business logic (database-agnostic)
│ ├── adapters/ # Database adapters
│ │ ├── base/ # Abstract interfaces
│ │ └── sqlalchemy/ # SQLAlchemy implementation
│ ├── api/ # FastAPI routes and dependencies
│ ├── security/ # JWT, hashing, rate limiting
│ ├── email/ # Email providers
│ └── settings.py # Configuration
├── tests/ # Test suite
├── examples/ # Example applications
└── docs/ # Documentation
Security
FastAuth follows security best practices:
- Password Hashing - Argon2 (OWASP recommended)
- JWT Tokens - Secure token generation and validation
- Rate Limiting - Protection against brute force
- Token Expiration - Configurable token lifetimes
- Refresh Token Rotation - Enhanced security
- SQL Injection Protection - Parameterized queries
- XSS Protection - Proper input validation
Security Recommendations
For production deployments:
- Use strong
JWT_SECRET_KEY(min 32 characters) - Enable HTTPS/TLS
- Enable email verification (
REQUIRE_EMAIL_VERIFICATION=true) - Use secure email provider (not console)
- Set appropriate token expiration times
- Enable rate limiting
- Monitor authentication logs
- Keep dependencies updated
Troubleshooting
Common Issues
Issue: "Invalid JWT secret key"
# Solution: Set a strong secret key
JWT_SECRET_KEY=your-very-long-secret-key-min-32-characters
Issue: "Email not being sent"
# Solution: Check email provider configuration
EMAIL_PROVIDER=console # For development
# Or configure SMTP settings for production
Issue: "Database connection failed"
# Solution: Verify database URL format
# SQLite: sqlite:///./app.db
# PostgreSQL: postgresql://user:pass@localhost/dbname
# MySQL: mysql://user:pass@localhost/dbname
Issue: "Rate limit exceeded"
# Solution: Adjust rate limit settings or wait for window to expire
LOGIN_RATE_LIMIT=10 # Increase limit
LOGIN_RATE_WINDOW=300 # 5 minutes
Getting Help
- Documentation: docs/
- Issues: GitHub Issues
- Discussions: GitHub Discussions
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built with FastAPI
- Database ORM: SQLModel
- Password hashing: Argon2
- JWT tokens: python-jose
Support
If you find FastAuth useful, please consider:
- Starring the repository ⭐
- Reporting bugs and suggesting features
- Contributing code or documentation
- Sharing with others
Made with ❤️ by Sreekar Nutulapati
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 sreekarnv_fastauth-0.2.1.tar.gz.
File metadata
- Download URL: sreekarnv_fastauth-0.2.1.tar.gz
- Upload date:
- Size: 31.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.13.2 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2085ddda4c155c8f615f0836047f2c0bb56fb163ab08164bce4eddf3694e7d3
|
|
| MD5 |
e80b9b2ac78ce9f8ceb101f1220cba0d
|
|
| BLAKE2b-256 |
0cd01549369f341db969cd5fb4c9913c9090282980dc464f39c44c1bd2e9ce47
|
File details
Details for the file sreekarnv_fastauth-0.2.1-py3-none-any.whl.
File metadata
- Download URL: sreekarnv_fastauth-0.2.1-py3-none-any.whl
- Upload date:
- Size: 51.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.13.2 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e9246b28cd9f1596dc0b641f898853c5d3e9c7c9f940a2eff53155152ec03b2
|
|
| MD5 |
8c19840b97b84fc1b17f30a6d5053f84
|
|
| BLAKE2b-256 |
a2ab05edd04860638df9095f686295ed5f226e8702cfcb46a835ea4bf00f9a6b
|