MyAuth Module
A reusable, modular authentication system for FastAPI applications with pluggable database backends.
Overview
This module provides a complete authentication solution designed to be deployed on internal PyPI servers and reused across multiple projects. It handles user registration, login/logout, token management, email verification, and password reset functionality.
Features
Core Authentication
- ✅ User registration with email and username
- ✅ Login/logout with email-based authentication
- ✅ JWT-based access tokens (30 minutes validity)
- ✅ Opaque refresh tokens stored in database (7 days validity)
- ✅ Password hashing with configurable bcrypt rounds
User Management
- ✅ Email verification with JWT tokens
- ✅ Password reset with secure random tokens (15 minutes validity)
- ✅ User roles management (flexible, no predefined roles)
- ✅ User settings storage (dict field)
- ✅ Account activation/deactivation
Password Security
- ✅ Strict password validation (via Pydantic):
- Minimum 8 characters
- At least 1 uppercase letter
- At least 1 lowercase letter
- At least 1 digit
- At least 1 special character
Architecture
- ✅ Abstract base classes for database persistence
- ✅ Multiple database implementations: MongoDB, SQLite, PostgreSQL
- ✅ Abstract email service interface with optional SMTP implementation
- ✅ Custom exceptions with FastAPI integration
- ✅ Synchronous implementation
- ✅ Ready-to-use FastAPI router with
/authprefix
Project Structure
├──src
│ my_auth/
│ ├── __init__.py
│ ├── models/ # Pydantic models
│ │ ├── user.py # User model with roles and settings
│ │ ├── token.py # Token models (access, refresh, reset)
│ │ └── email_verification.py # Email verification models
│ ├── core/ # Business logic
│ │ ├── auth.py # Authentication service
│ │ ├── password.py # Password hashing/verification
│ │ └── token.py # Token generation/validation
│ ├── persistence/ # Database abstraction
│ │ ├── base.py # Abstract base classes
│ │ ├── mongodb.py # MongoDB implementation
│ │ ├── sqlite.py # SQLite implementation
│ │ └── postgresql.py # PostgreSQL implementation
│ ├── api/ # FastAPI routes
│ │ └── routes.py # All authentication endpoints
│ ├── email/ # Email service
│ │ ├── base.py # Abstract interface
│ │ └── smtp.py # SMTP implementation (optional)
│ ├── exceptions.py # Custom exceptions
│ └── config.py # Configuration classes
├── tests
User Model
class User:
id: str # Unique identifier
email: str # Unique, required
username: str # Required, non-unique
hashed_password: str # Bcrypt hashed
roles: list[str] # Free-form roles, no defaults
user_settings: dict # Custom user settings
is_verified: bool # Email verification status
is_active: bool # Account active status
created_at: datetime
updated_at: datetime
Token Management
Token Types
The module uses a unified tokens collection with a discriminator field:
- Access Token (JWT): 30 minutes validity, stateless
- Refresh Token (Opaque): 7 days validity, stored in DB
- Password Reset Token (Random): 15 minutes validity, stored in DB
- Email Verification Token (JWT): Stateless, no DB storage
Token Storage
All tokens requiring storage (refresh and password reset) are kept in a single tokens collection/table with a token_type discriminator field.
API Endpoints
The module exposes a pre-configured FastAPI router with the following endpoints:
POST /auth/register # User registration
POST /auth/login # Login (email + password)
POST /auth/logout # Logout (revokes refresh token)
POST /auth/refresh # Refresh access token
POST /auth/password-reset-request # Request password reset
POST /auth/password-reset # Reset password with token
POST /auth/verify-email-request # Request email verification
POST /auth/verify-email # Verify email with token
GET /auth/me # Get current user info
Installation
Dependencies
Core dependencies:
pip install fastapi pydantic pydantic-settings python-jose[cryptography] passlib[bcrypt] python-multipart
Database-specific dependencies:
- MongoDB:
pip install pymongo - SQLite: Built-in (no additional dependency)
- PostgreSQL:
pip install psycopg2-binary
Optional email dependency:
- SMTP:
pip install secure-smtplib
Usage
Basic Setup
from fastapi import FastAPI
from auth_module import AuthService
from auth_module.persistence.mongodb import MongoUserRepository, MongoTokenRepository
from auth_module.api import auth_router
# Initialize repositories
user_repo = MongoUserRepository(connection_string="mongodb://localhost:27017/mydb")
token_repo = MongoTokenRepository(connection_string="mongodb://localhost:27017/mydb")
# Initialize auth service
auth_service = AuthService(
user_repository=user_repo,
token_repository=token_repo,
jwt_secret="your-secret-key-here",
access_token_expire_minutes=30,
refresh_token_expire_days=7,
password_reset_token_expire_minutes=15,
password_hash_rounds=12
)
# Create FastAPI app and include auth router
app = FastAPI()
app.include_router(auth_router) # Mounts at /auth prefix
Using Different Databases
SQLite
from auth_module.persistence.sqlite import SQLiteUserRepository, SQLiteTokenRepository
user_repo = SQLiteUserRepository(db_path="./auth.db")
token_repo = SQLiteTokenRepository(db_path="./auth.db")
PostgreSQL
from auth_module.persistence.postgresql import PostgreSQLUserRepository, PostgreSQLTokenRepository
user_repo = PostgreSQLUserRepository(
host="localhost",
port=5432,
database="mydb",
user="postgres",
password="secret"
)
token_repo = PostgreSQLTokenRepository(...)
Email Service Configuration
from auth_module.email.smtp import SMTPEmailService
email_service = SMTPEmailService(
host="smtp.gmail.com",
port=587,
username="your-email@gmail.com",
password="your-app-password",
use_tls=True
)
auth_service = AuthService(
user_repository=user_repo,
token_repository=token_repo,
email_service=email_service, # Optional
...
)
Custom Email Service
Implement your own email service by extending the abstract base class:
from auth_module.email.base import EmailService
class CustomEmailService(EmailService):
def send_verification_email(self, email: str, token: str) -> None:
# Your implementation (SendGrid, AWS SES, etc.)
pass
def send_password_reset_email(self, email: str, token: str) -> None:
# Your implementation
pass
Error Handling
The module uses custom exceptions that are automatically converted to appropriate HTTP responses:
InvalidCredentialsError→ 401 UnauthorizedUserAlreadyExistsError→ 409 ConflictUserNotFoundError→ 404 Not FoundInvalidTokenError→ 401 UnauthorizedRevokedTokenError→ 401 UnauthorizedExpiredTokenError→ 401 UnauthorizedEmailNotVerifiedError→ 403 ForbiddenAccountDisabledError→ 403 Forbidden
Configuration Options
AuthService(
user_repository: UserRepository, # Required
token_repository: TokenRepository, # Required
jwt_secret: str, # Required
jwt_algorithm: str = "HS256", # Optional
access_token_expire_minutes: int = 30, # Optional
refresh_token_expire_days: int = 7, # Optional
password_reset_token_expire_minutes: int = 15, # Optional
password_hash_rounds: int = 12, # Optional (bcrypt cost)
email_service: EmailService = None # Optional
)
Testing
The module is fully testable with pytest. Test fixtures are provided for each database implementation.
pytest tests/
Security Considerations
- Passwords are hashed using bcrypt with configurable rounds
- JWT tokens are signed with HS256 (configurable)
- Refresh tokens are opaque and stored securely
- Password reset tokens are single-use and expire after 15 minutes
- Email verification tokens are stateless JWT
- Rate limiting should be implemented at the application level
- HTTPS should be enforced by the application
Future Enhancements (Not Included)
- Multi-factor authentication (2FA/MFA)
- Rate limiting on login attempts
- OAuth2 provider integration
- Session management (multiple device tracking)
- Account lockout after failed attempts
License
[Your License Here]
Contributing
[Your Contributing Guidelines Here]