Skip to main content

A complete OAuth2 authentication plugin for FastAPI with user management, roles, and permissions

Project description

FastAPI Auth Plugin

A production-ready, plug-and-play authentication system for FastAPI applications with OAuth2 Password Flow, JWT tokens, role-based access control (RBAC), and PostgreSQL backend.

Features

  • OAuth2 Password Flow with JWT access and refresh tokens
  • Google OAuth Integration - Sign in with Google (optional)
  • User Management - Registration, login, profile management
  • Role-Based Access Control (RBAC) - Flexible roles and permissions system
  • PostgreSQL Backend with SQLAlchemy ORM
  • Secure Password Hashing using Bcrypt
  • FastAPI Dependencies for easy route protection
  • Granular Permissions with resource:action pattern
  • Production Ready with comprehensive error handling
  • Fully Typed with Pydantic models
  • Extensible - Easy to customize and extend

Installation

pip install fastapi-auth-plugin

Or install from source:

cd fastapi-auth-plugin
pip install -e .

Quick Start

1. Set up environment variables

Create a .env file:

DATABASE_URL=postgresql://postgres:password@localhost:5432/your_db
SECRET_KEY=your-secret-key-here-change-in-production

Generate a secure secret key:

python -c "import secrets; print(secrets.token_urlsafe(32))"

2. Integrate into your FastAPI app

from fastapi import FastAPI, Depends
from fastapi_auth_plugin import auth_router, get_current_user, init_db, models

app = FastAPI()

# Initialize database on startup
@app.on_event("startup")
async def startup():
    init_db()

# Include authentication routes
app.include_router(auth_router, prefix="/api")

# Protected route example
@app.get("/protected")
def protected_route(user: models.User = Depends(get_current_user)):
    return {"message": f"Hello {user.username}!"}

3. Run your application

uvicorn main:app --reload

Visit http://localhost:8000/docs for interactive API documentation.

4. Default credentials

The system creates a default superuser on first run:

Username: admin
Password: admin123

WARNING: CHANGE THIS PASSWORD IMMEDIATELY IN PRODUCTION!

Google OAuth Setup (Optional)

The plugin supports Google OAuth for easier user authentication and registration.

1. Create Google OAuth Credentials

  1. Go to Google Cloud Console
  2. Create a new project or select an existing one
  3. Enable the Google+ API (People API)
  4. Go to CredentialsCreate CredentialsOAuth 2.0 Client ID
  5. Configure the OAuth consent screen
  6. For Application type, select Web application
  7. Add authorized redirect URIs:
    • http://localhost:8000/api/auth/google/callback (for web/API usage)
    • http://localhost:9999/callback (for Qt desktop client - automated flow)
    • https://yourdomain.com/api/auth/google/callback (production)
  8. Copy your Client ID and Client Secret

2. Configure Environment Variables

Add to your .env file:

GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=http://localhost:8000/api/auth/google/callback

3. Register OAuth Providers

Update your FastAPI app to register OAuth providers on startup:

from fastapi import FastAPI
from fastapi_auth_plugin import auth_router, init_db, register_oauth_providers

app = FastAPI()

@app.on_event("startup")
async def startup():
    init_db()
    register_oauth_providers()  # Register Google OAuth

app.include_router(auth_router, prefix="/api")

4. Use Google Login

Via API (Web Flow):

  1. Direct users to GET /api/auth/google/login
  2. They'll be redirected to Google for authentication
  3. After approval, Google redirects to /api/auth/google/callback
  4. The callback returns JWT tokens in JSON format

Via Qt Client (Device Flow - Recommended):

  • Click the "🔐 Login with Google" button
  • Authenticate in your browser
  • The tokens are automatically retrieved via polling
  • No manual copy/paste required!

This uses a modern backend-mediated OAuth flow similar to VS Code, GitHub CLI, and other desktop applications.

How Device Flow Works

  1. Client calls /auth/google/device/initiate to get a unique state and auth URL
  2. Client opens the auth URL in the user's browser
  3. User authenticates with Google, which redirects to the backend
  4. Backend stores JWT tokens associated with the state
  5. Client polls /auth/google/device/poll with the state until tokens are ready
  6. Client receives tokens automatically

This approach eliminates the need for local HTTP servers or redirect URI registration on arbitrary ports.

Google OAuth Features

  • No password required - Users authenticate with their Google account
  • Auto account creation - New accounts are created automatically
  • Account linking - Existing users can link their Google account
  • Profile sync - User email and profile picture from Google
  • Same JWT tokens - Works seamlessly with existing authentication flow
  • Desktop-friendly - Modern device flow for desktop/CLI applications

Google OAuth API Endpoints

Method Endpoint Description
GET /auth/google/login Initiate Google OAuth flow (web)
GET /auth/google/callback Handle Google OAuth callback
GET /auth/google/device/initiate Initiate device/desktop OAuth flow
GET /auth/google/device/poll Poll for OAuth tokens (device flow)
POST /auth/google/exchange Exchange OAuth code for tokens (legacy)

Usage Examples

Protect Routes with Authentication

from fastapi import Depends
from fastapi_auth_plugin import get_current_user, models

@app.get("/profile")
def get_profile(user: models.User = Depends(get_current_user)):
    return {
        "username": user.username,
        "email": user.email,
        "roles": [role.name for role in user.roles]
    }

Require Specific Roles

from fastapi_auth_plugin import require_role

@app.get("/admin/dashboard")
def admin_dashboard(user = Depends(require_role("admin", "superuser"))):
    return {"message": "Admin access granted"}

Require Specific Permissions

from fastapi_auth_plugin import require_permission

@app.delete("/posts/{post_id}")
def delete_post(
    post_id: int,
    user = Depends(require_permission("posts", "delete"))
):
    return {"message": f"Post {post_id} deleted"}

Optional Authentication

from fastapi_auth_plugin import optional_user

@app.get("/posts")
def list_posts(user = Depends(optional_user)):
    if user:
        # Show personalized content
        return {"posts": [...], "user": user.username}
    else:
        # Show public content
        return {"posts": [...]}

API Endpoints

Authentication

Method Endpoint Description Auth Required
POST /auth/register Register new user No
POST /auth/login Login (OAuth2) No
POST /auth/refresh Refresh access token No
POST /auth/logout Logout Yes
GET /auth/me Get current user profile Yes
PUT /auth/me Update current user Yes

User Management (Admin)

Method Endpoint Description Permission
GET /auth/users List all users users:read
GET /auth/users/{id} Get user by ID users:read
PUT /auth/users/{id} Update user users:write
DELETE /auth/users/{id} Delete user users:delete
POST /auth/users/{id}/roles Assign roles users:write

Role Management

Method Endpoint Description Permission
GET /auth/roles List all roles roles:read
POST /auth/roles Create role Superuser
PUT /auth/roles/{id} Update role Superuser
DELETE /auth/roles/{id} Delete role Superuser

Permissions

Method Endpoint Description Permission
GET /auth/permissions List all permissions permissions:read
POST /auth/permissions Create permission Superuser

Configuration

All settings can be configured via environment variables:

from fastapi_auth_plugin import AuthSettings

# Custom configuration
settings = AuthSettings(
    DATABASE_URL="postgresql://user:pass@localhost/db",
    SECRET_KEY="your-secret-key",
    ACCESS_TOKEN_EXPIRE_MINUTES=30,
    REFRESH_TOKEN_EXPIRE_DAYS=7,
    ALGORITHM="HS256"
)

Available Settings

Variable Default Description
DATABASE_URL postgresql://... PostgreSQL connection URL
SECRET_KEY (required) Secret key for JWT signing
ALGORITHM HS256 JWT algorithm
ACCESS_TOKEN_EXPIRE_MINUTES 30 Access token lifetime
REFRESH_TOKEN_EXPIRE_DAYS 7 Refresh token lifetime
TOKEN_URL /auth/login OAuth2 token endpoint
GOOGLE_CLIENT_ID None Google OAuth client ID (optional)
GOOGLE_CLIENT_SECRET None Google OAuth client secret (optional)
GOOGLE_REDIRECT_URI http://localhost:8000/api/auth/google/callback Google OAuth redirect URI

Database Schema

User Model

  • id: int (primary key)
  • email: str (unique)
  • username: str (unique)
  • hashed_password: str (nullable for OAuth users)
  • is_active: bool
  • is_superuser: bool
  • google_id: str (nullable, unique - Google OAuth user ID)
  • google_picture: str (nullable - Google profile picture URL)
  • oauth_provider: str (nullable - 'google', 'github', etc.)
  • created_at: datetime
  • updated_at: datetime
  • roles: list[Role] (many-to-many)

Role Model

  • id: int (primary key)
  • name: str (unique)
  • description: str
  • permissions: list[Permission] (many-to-many)
  • users: list[User] (many-to-many)

Permission Model

  • id: int (primary key)
  • name: str (unique, e.g., "users:read")
  • resource: str (e.g., "users")
  • action: str (e.g., "read")
  • description: str
  • roles: list[Role] (many-to-many)

Default Roles & Permissions

The system creates three default roles on initialization:

Superuser

  • All permissions
  • Full system access

Admin

  • users:read, users:write, users:delete
  • roles:read

User (default)

  • users:read (own profile only)

Running Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# With coverage
pytest --cov=fastapi_auth_plugin --cov-report=html

Security Best Practices

  1. Always use HTTPS in production
  2. Change default admin password immediately
  3. Use strong, randomly generated SECRET_KEY
  4. Set appropriate CORS policies
  5. Implement rate limiting (consider using slowapi)
  6. Use environment variables for sensitive data
  7. Regularly update dependencies
  8. Enable PostgreSQL SSL in production
  9. Monitor and log authentication attempts

Example Application

See examples/simple_app.py for a complete working example showing:

  • Database initialization
  • Protected routes
  • Role-based endpoints
  • Permission-based endpoints
  • Public and private content

Run the example:

cd examples
uvicorn simple_app:app --reload

License

MIT License - see LICENSE file for details

Changelog

0.1.0 (2024-01-06)

  • Initial release
  • OAuth2 Password Flow
  • JWT authentication
  • Role-based access control
  • PostgreSQL backend
  • Comprehensive test suite

Credits

Built with:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_auth_plugin-0.1.4.tar.gz (39.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_auth_plugin-0.1.4-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_auth_plugin-0.1.4.tar.gz.

File metadata

  • Download URL: fastapi_auth_plugin-0.1.4.tar.gz
  • Upload date:
  • Size: 39.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_auth_plugin-0.1.4.tar.gz
Algorithm Hash digest
SHA256 24623d9c1914cd4f9ac441f709e3d89d3d1c12b8ace6a890174f2f5313d077ed
MD5 cd4582830944db2b68f2e1d63d736533
BLAKE2b-256 ae080b2bfb649daa562c2324fd211f26ee583516cb709973c90fa19e1ee95249

See more details on using hashes here.

File details

Details for the file fastapi_auth_plugin-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_auth_plugin-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 27907df74899143acd8d62a316cfc6a7abd58bbff884a769b33c099620ccd59d
MD5 ae592a790ac353ab4b6a20830b17e5a0
BLAKE2b-256 bbd7f9b164c57a93e6d945c9021d3e901016d37fb418c3d255ed5faf7aefe06d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page