Files
core/docs/auth/architecture.md
Untone fb98a1c6c8
All checks were successful
Deploy on push / deploy (push) Successful in 4m32s
[0.9.28] - OAuth/Auth with httpOnly cookie
2025-09-28 12:22:37 +03:00

8.4 KiB
Raw Blame History

🏗️ Архитектура системы авторизации Discours Core

🎯 Обзор архитектуры 2025

Модульная система авторизации с httpOnly cookies для максимальной безопасности и единообразия.

Ключевые принципы:

  • 🍪 httpOnly cookies для ВСЕХ типов авторизации (OAuth + Email/Password)
  • 🛡️ Максимальная безопасность - защита от XSS и CSRF
  • 🔄 Единообразие - один механизм для всех провайдеров
  • 📱 Автоматическое управление - браузер сам отправляет cookies

Хранение данных:

  • Сессии → Redis (JWT токены) + httpOnly cookies (передача)
  • OAuth токены → Redis (для API интеграций)
  • Пользователи → PostgreSQL (основные данные + OAuth связи)

📊 Схема потоков данных

graph TB
    subgraph "Frontend"
        FE[Web Frontend]
        MOB[Mobile App]
        API[API Clients]
    end

    subgraph "Auth Layer"
        MW[AuthMiddleware]
        DEC[GraphQL Decorators]
        UTILS[Auth Utils]
    end

    subgraph "Token Managers"
        STM[SessionTokenManager]
        VTM[VerificationTokenManager]
        OTM[OAuthTokenManager]
        BTM[BatchTokenOperations]
        MON[TokenMonitoring]
    end

    subgraph "Storage"
        REDIS[(Redis)]
        DB[(PostgreSQL)]
    end

    subgraph "External OAuth"
        GOOGLE[Google]
        GITHUB[GitHub]
        FACEBOOK[Facebook]
        VK[VK]
        YANDEX[Yandex]
    end

    FE --> MW
    MOB --> MW
    API --> MW
    
    MW --> STM
    MW --> UTILS
    
    DEC --> STM
    UTILS --> STM
    
    STM --> REDIS
    VTM --> REDIS
    OTM --> REDIS
    BTM --> REDIS
    MON --> REDIS
    
    STM --> DB
    
    OTM --> GOOGLE
    OTM --> GITHUB
    OTM --> FACEBOOK
    OTM --> VK
    OTM --> YANDEX

🏗️ Диаграмма компонентов

Примечание: Токены хранятся только в Redis, PostgreSQL используется только для пользовательских данных и OAuth связей.

graph TB
    subgraph "HTTP Layer"
        REQ[HTTP Request]
        RESP[HTTP Response]
    end

    subgraph "Middleware Layer"
        AUTH_MW[AuthMiddleware]
        UTILS[Auth Utils]
    end

    subgraph "Token Management"
        STM[SessionTokenManager]
        VTM[VerificationTokenManager]
        OTM[OAuthTokenManager]
        BTM[BatchTokenOperations]
        MON[TokenMonitoring]
    end

    subgraph "Storage"
        REDIS[(Redis)]
        DB[(PostgreSQL)]
    end

    subgraph "External"
        OAUTH_PROV[OAuth Providers]
    end

    REQ --> AUTH_MW
    AUTH_MW --> UTILS
    UTILS --> STM
    
    STM --> REDIS
    VTM --> REDIS
    OTM --> REDIS
    BTM --> REDIS
    MON --> REDIS
    
    STM --> DB
    OTM --> OAUTH_PROV
    
    STM --> RESP
    VTM --> RESP
    OTM --> RESP

🔐 OAuth Flow (httpOnly cookies)

sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant R as Redis
    participant P as OAuth Provider

    U->>F: Click "Login with Provider"
    F->>B: GET /oauth/{provider}/login
    B->>R: Store OAuth state (TTL: 10 min)
    B->>P: Redirect to Provider
    P->>U: Show authorization page
    U->>P: Grant permission
    P->>B: GET /oauth/{provider}/callback?code={code}&state={state}
    B->>R: Verify state
    B->>P: Exchange code for token
    P->>B: Return access token + user data
    B->>B: Create/update user
    B->>B: Generate JWT session token
    B->>R: Store session in Redis
    B->>F: Redirect + Set httpOnly cookie
    Note over B,F: Cookie: session_token=JWT<br/>HttpOnly, Secure, SameSite=lax
    F->>U: User logged in (cookie automatic)
    
    Note over F,B: All subsequent requests
    F->>B: GraphQL with credentials: 'include'
    Note over F,B: Browser automatically sends cookie

🔄 Session Management (httpOnly cookies)

stateDiagram-v2
    [*] --> Anonymous
    Anonymous --> Authenticating: Login attempt (OAuth/Email)
    Authenticating --> Authenticated: Valid JWT + httpOnly cookie set
    Authenticating --> Anonymous: Invalid credentials
    Authenticated --> Refreshing: Token near expiry
    Refreshing --> Authenticated: New httpOnly cookie set
    Refreshing --> Anonymous: Refresh failed
    Authenticated --> Anonymous: Logout (cookie deleted)
    Authenticated --> Anonymous: Token expired (cookie invalid)
    
    note right of Authenticated
        All requests include
        httpOnly cookie automatically
        via credentials: 'include'
    end note

🗄️ Redis структура данных

# JWT Sessions (основные - передаются через httpOnly cookies)
session:{user_id}:{token}     # Hash: {user_id, username, device_info, last_activity}
user_sessions:{user_id}       # Set: {token1, token2, ...}

# OAuth Tokens (для API интеграций - НЕ для аутентификации)
oauth_access:{user_id}:{provider}   # JSON: {token, expires_in, scope}
oauth_refresh:{user_id}:{provider}  # JSON: {token, provider_data}

# OAuth State (временные - для CSRF защиты)
oauth_state:{state}                 # JSON: {provider, redirect_uri, code_verifier} TTL: 10 мин

# Verification Tokens (email подтверждения и т.д.)
verification_token:{token}    # JSON: {user_id, type, data, created_at}

🔄 Изменения в архитектуре 2025:

Убрано:

  • Токены в URL параметрах (небезопасно)
  • localStorage для основных токенов (уязвимо к XSS)
  • Bearer заголовки для веб-приложений (сложнее управлять)

Добавлено:

  • httpOnly cookies для всех типов авторизации
  • Автоматическая отправка cookies браузером
  • SameSite защита от CSRF
  • Secure flag для HTTPS

Примеры Redis команд

# Поиск сессий пользователя
redis-cli --scan --pattern "session:123:*"

# Получение данных сессии
redis-cli HGETALL "session:123:your_token_here"

# Проверка TTL
redis-cli TTL "session:123:your_token_here"

# Поиск OAuth токенов
redis-cli --scan --pattern "oauth_access:123:*"

🔒 Security Components

graph TD
    subgraph "Input Validation"
        EMAIL[Email Format]
        PASS[Password Strength]
        TOKEN[JWT Validation]
    end

    subgraph "Authentication"
        BCRYPT[bcrypt + SHA256]
        JWT_SIGN[JWT Signing]
        OAUTH_VERIFY[OAuth Verification]
    end

    subgraph "Authorization"
        RBAC[RBAC System]
        PERM[Permission Checks]
        RESOURCE[Resource Access]
    end

    subgraph "Session Security"
        TTL[Redis TTL]
        REVOKE[Token Revocation]
        REFRESH[Secure Refresh]
    end

    EMAIL --> BCRYPT
    PASS --> BCRYPT
    TOKEN --> JWT_SIGN

    BCRYPT --> RBAC
    JWT_SIGN --> RBAC
    OAUTH_VERIFY --> RBAC

    RBAC --> PERM
    PERM --> RESOURCE

    RESOURCE --> TTL
    RESOURCE --> REVOKE
    RESOURCE --> REFRESH

Performance & Scaling

Горизонтальное масштабирование

  • Stateless JWT токены
  • Redis Cluster для высокой доступности
  • Load Balancer aware session management

Оптимизации

  • Connection pooling для Redis
  • Batch operations для массовых операций (100-1000 токенов)
  • Pipeline использование для атомарности
  • SCAN вместо KEYS для безопасности

Мониторинг производительности

from auth.tokens.monitoring import TokenMonitoring

monitoring = TokenMonitoring()

# Статистика токенов
stats = await monitoring.get_token_statistics()
# {
#   "session_tokens": 150,
#   "verification_tokens": 5,
#   "oauth_access_tokens": 25,
#   "memory_usage": 1048576
# }

# Health check
health = await monitoring.health_check()
# {"status": "healthy", "redis_connected": True}