Skip to Content
Ai LogAuthentication Implementation Summary

Authentication Implementation Summary

What Was Implemented

A complete JWT-based authentication system for the DermaDetect API Gateway.

Key Features

βœ… JWT Authentication

  • Access tokens (30 min expiry)
  • Refresh tokens (30 days expiry) with rotation
  • HS256 algorithm with configurable secret key

βœ… User Management

  • User registration and login
  • Role-based access control (patient, physician, admin)
  • Multi-tenancy support via tenants table
  • Physician-specific profiles

βœ… Password Management

  • bcrypt password hashing
  • Password reset flow with secure tokens
  • Password change for authenticated users

βœ… Database Schema

  • users - Main authentication table
  • physicians - Physician profiles
  • tenants - Multi-tenancy
  • refresh_tokens - Token storage
  • password_reset_tokens - Reset tokens

βœ… API Endpoints (/api/auth)

  • POST /register - Create account
  • POST /login - Authenticate
  • POST /refresh - Refresh tokens
  • GET /me - Get current user
  • POST /request-reset - Request password reset
  • POST /reset-password - Reset password
  • POST /change-password - Change password

βœ… Migration Tools

  • Database migration for auth tables
  • Physician migration script from dd_api.groups (44 physicians)
  • Auto-generates password reset tokens

βœ… Documentation

  • Comprehensive API documentation
  • Client integration examples
  • Security best practices

Quick Start

1. Run Migrations

cd services/api_gateway uv sync uv run alembic upgrade head

2. Migrate Existing Physicians (Optional)

uv run python -m scripts.migrate_physicians

This will output password reset URLs for all 44 physicians.

3. Start the Server

uv run uvicorn src.main:app --reload --port 8000

4. Test the API

# Register a new user curl -X POST http://localhost:8000/api/auth/register \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"password123","role":"patient"}' # Login curl -X POST http://localhost:8000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"password123"}' # Get current user (replace TOKEN with access_token from login) curl http://localhost:8000/api/auth/me \ -H "Authorization: Bearer TOKEN"

Dependencies Added

"python-jose[cryptography]>=3.3.0" # JWT "passlib[bcrypt]>=1.7.4" # Password hashing "email-validator>=2.0.0" # Email validation

File Structure

services/api_gateway/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ api/ β”‚ β”‚ β”œβ”€β”€ auth.py # Auth endpoints β”‚ β”‚ └── auth_test.py # Auth tests β”‚ β”œβ”€β”€ core/ β”‚ β”‚ β”œβ”€β”€ auth.py # JWT & password utilities β”‚ β”‚ └── dependencies.py # Auth dependencies β”‚ β”œβ”€β”€ schemas/ β”‚ β”‚ └── auth.py # Pydantic schemas β”‚ └── database/ β”‚ └── models.py # Updated with auth models β”œβ”€β”€ scripts/ β”‚ └── migrate_physicians.py # Migration script └── alembic/versions/ └── f788c6af4f90_*.py # Auth tables migration

Configuration

Set in .env or environment variables:

SECRET_KEY=your-secret-key-here # Auto-generated if not set DATABASE_URL=postgresql://... # Default: localhost

Protected Routes Example

from typing import Annotated from fastapi import Depends from core.dependencies import get_current_user, get_current_physician from database.models import User @router.get("/protected") def protected_route( current_user: Annotated[User, Depends(get_current_user)] ): return {"user_id": str(current_user.uuid)} @router.get("/physician-only") def physician_route( current_user: Annotated[User, Depends(get_current_physician)] ): return {"physician_id": str(current_user.physician.uuid)}

Client Integration (React Native / Web)

// Register const { access_token, refresh_token } = await fetch('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'user@example.com', password: 'password123', role: 'patient' }) }).then(r => r.json()); // Use access token const response = await fetch('/api/protected', { headers: { 'Authorization': `Bearer ${access_token}` } }); // Refresh when needed const newTokens = await fetch('/api/auth/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refresh_token }) }).then(r => r.json());

Next Steps

  1. βœ… Basic auth system implemented
  2. πŸ”² Email service integration - For password resets
  3. πŸ”² Email verification - Verify user emails
  4. πŸ”² Rate limiting - Prevent brute force attacks
  5. πŸ”² 2FA/MFA - Additional security layer
  6. πŸ”² OAuth providers - Google, Apple Sign-In
  7. πŸ”² SAML/SSO - Enterprise authentication

Migration from Legacy System

The USER_MIGRATION_ANALYSIS.md document contains detailed analysis of the legacy data:

  • Physicians: 44 users migrated from dd_api.groups
  • Patients: Cannot migrate (only Firebase UIDs, no email/password)
  • Tenants: 19 unique vendors/tenants created
  • Strategy: Physicians require password reset, patients remain as anonymous legacy references

Documentation

Full documentation available at:

  • /docs/app/services/api-gateway/authentication/page.mdx
  • API docs: http://localhost:8000/docs (when server is running)
Last updated on