Перейти к содержанию

Authentication Flow - Критический путь аутентификации (Integration-Only)

Дата обновления: 2025-11-13 Архитектура: Integration-Only (EMAIL-FIRST MANDATORY)

Архитектурные принципы

  • ✅ ОБЯЗАТЕЛЬНО: Email MANDATORY как единственный identifier
  • ✅ ОБЯЗАТЕЛЬНО: Supabase Auth (Google OAuth + email/password)
  • ❌ ЗАПРЕТ: Web3 wallet signature verification (Integration-Only)
  • ✅ ОБЯЗАТЕЛЬНО: Админы только в config.yaml (НЕ в БД)
  • ✅ ОБЯЗАТЕЛЬНО: Clean Architecture (Handler → Service → Repository)

Компоненты системы

Backend Stack

Компонент Файл Роль
Admin Router /backend/shared/routing/admin_auth_router.go Admin HTTP endpoints
User Router /backend/shared/routing/user_auth_router.go User HTTP endpoints
Service /backend/shared/services/admin_auth_service.go Бизнес-логика
Supabase Handler /backend/auth/service/supabase_auth_handler.go Supabase integration
Middleware /backend/shared/middleware/auth_middleware.go JWT проверка
Repository /backend/auth/repository/auth_repository_core.go Данные пользователей

Frontend Stack

Компонент Файл Роль
Context /frontend/user-app/src/lib/supabase-auth-context.tsx React Context
Service /frontend/user-app/src/lib/services/auth-service.ts API calls
Components /frontend/user-app/src/components/auth/ UI компоненты
Supabase Client /frontend/shared/lib/supabase-client.ts Supabase integration

API Endpoints (Integration-Only)

  • POST /api/auth/supabase/login - Вход через Supabase JWT
  • POST /api/auth/supabase/callback - OAuth callback handling
  • GET /api/auth/user/profile - Получение профиля пользователя

Детальный Flow

1. Supabase Authentication (Integration-Only)

sequenceDiagram
    participant U as User
    participant F as Frontend
    participant S as Supabase Auth
    participant G as Google OAuth

    U->>F: Открывает приложение
    F->>F: SupabaseAuthContext инициализируется
    F->>S: supabase.auth.getUser()

    alt Пользователь не залогинен
        F->>U: Показать login screen
        U->>F: Клик "Войти через Google"
        F->>S: signInWithOAuth({provider: 'google'})
        S->>G: OAuth redirect
        G->>U: Google login screen
        U->>G: Email + password
        G->>S: OAuth callback с email
        S->>F: User session с email
    else Пользователь залогинен
        S->>F: Existing session
    end

    F->>F: Сохраняет email в state

2. Backend Authentication Process (Integration-Only)

sequenceDiagram
    participant F as Frontend
    participant S as Supabase Auth
    participant B as Backend
    participant C as Config
    participant DB as Database

    F->>S: supabase.auth.getSession()
    S->>F: access_token + user.email

    F->>B: POST /api/auth/supabase/login
    Note right of F: {Authorization: Bearer supabase_jwt}

    B->>B: Верификация Supabase JWT (JWKS)
    B->>B: Извлечение email из JWT claims

    alt Email отсутствует
        B-->>F: 400 Bad Request - Email MANDATORY
    else Email присутствует
        B->>C: Проверка email в config.yaml
        alt Admin email
            C-->>B: Найден в ADMIN_EMAILS
        else Regular user
            C-->>B: НЕ найден в ADMIN_EMAILS
        end

        B->>DB: Создать/найти пользователя по email
        DB-->>B: User data
        B->>B: Генерация Saga JWT токена с email claims
        B-->>F: {token, user, isAdmin}
    end

    F->>F: localStorage.setItem('auth_token', token)

3. Защита маршрутов (Integration-Only)

sequenceDiagram
    participant F as Frontend
    participant M as AuthMiddleware
    participant S as AuthService
    participant DB as Database

    F->>M: HTTP request с Authorization header
    M->>M: Извлечь Saga JWT токен
    M->>S: Валидация токена
    S->>S: jwt.verify(token)

    alt Токен валиден
        S->>S: Извлечь email из JWT claims
        S->>DB: Найти пользователя по email (MANDATORY)
        DB-->>S: User data
        S-->>M: Authenticated user
        M->>M: req.user = user (с email identifier)
        Note right of M: Запрос продолжается
    else Токен невалиден или нет email
        M-->>F: 401 Unauthorized
    end

Критические точки безопасности

1. Конфигурационная безопасность (Integration-Only)

ПРИНЦИП: Админы НЕ в базе данных, только в config.yaml

# config/auth.yaml
ADMIN_EMAILS:
  - "admin@saga-test.com"           # Primary admin
  - "operator@saga-test.com"        # Operations admin
  - "finance@saga-test.com"         # Finance admin

Почему это безопасно:

  • ❌ БД может быть скомпрометирована
  • ✅ Конфигурация контролируется на уровне deployment
  • ✅ Нет SQL injection на админские роли
  • ✅ Immutable deployment-time security
  • ✅ Email verification через Google OAuth

2. Supabase JWT Verification (Integration-Only)

Процесс верификации Supabase JWT:

// Псевдокод из backend
func VerifySupabaseJWT(token string) (*SupabaseClaims, error) {
    // 1. Получение JWKS от Supabase
    jwks, err := getSupabaseJWKS()
    if err != nil {
        return nil, err
    }

    // 2. Верификация подписи JWT
    claims, err := jwt.ParseWithClaims(token, &SupabaseClaims{}, jwks.keyFunc)
    if err != nil {
        return nil, err
    }

    // 3. Проверка email claim
    if claims.Email == "" {
        return nil, errors.New("email is MANDATORY in JWT claims")
    }

    return claims, nil
}

Почему это безопасно:

  • ✅ JWT подписан Supabase криптографическими ключами
  • ✅ JWKS rotation обеспечивает актуальные ключи
  • ✅ Email верифицирован через Google OAuth
  • ✅ Expiration time защищает от replay attacks

3. JWT Security (Integration-Only)

Структура Saga JWT токена:

{
  "user_id": "uuid-here",
  "email": "admin@saga-test.com",
  "full_name": "Admin User",
  "is_admin": true,
  "exp": 1640995200,
  "iat": 1640908800
}

Защитные механизмы:

  • ✅ Short expiration time (24 часа)
  • ✅ Strong signing key from config
  • ✅ Stateless verification (no session storage)

4. Rate Limiting & CORS

Защита от атак:

  • Rate limiting на auth endpoints
  • CORS protection для cross-origin requests
  • Request size limits
  • Timeout protection

База данных интеграция

Users Table Schema (Integration-Only)

CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,   -- PRIMARY IDENTIFIER
    full_name VARCHAR(255),
    status VARCHAR(20) NOT NULL DEFAULT 'active',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    last_login_at TIMESTAMPTZ,
    -- НЕТ полей: wallet_address, is_admin (админы в config.yaml)
);

Sessions Management

CREATE TABLE sessions (
    id UUID PRIMARY KEY,
    user_id UUID REFERENCES users(id),
    token_hash VARCHAR(256) NOT NULL,
    expires_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);

Принципы (Integration-Only):

  • ✅ Email как ЕДИНСТВЕННЫЙ identifier
  • ❌ НЕ храним admin статус в БД
  • ❌ НЕ используем wallet addresses
  • ✅ Только email-based user данные
  • ✅ JWT токены для stateless auth

Мониторинг и логирование

Критические события для логирования (Integration-Only):

  1. Успешная аутентификация: user_id, email, is_admin, auth_provider
  2. Неуспешные попытки: email, failure_reason, supabase_error
  3. Admin действия: все действия админов с полным audit trail
  4. Token expiration: мониторинг истечений токенов
  5. Suspicious activity: множественные неуспешные попытки с одного email
  6. Email mandatory violations: попытки создать пользователя без email

Метрики безопасности:

  • Количество уникальных email регистраций
  • Частота неуспешных аутентификаций
  • Admin actions frequency
  • Token refresh patterns
  • Supabase OAuth success rate

Troubleshooting Guide (Integration-Only)

Проблема: "Email is MANDATORY - authentication failed"

Возможные причины:

  1. Supabase JWT не содержит email claim
  2. Google OAuth не вернул email
  3. Пользователь отказал в доступе к email

Диагностика:

# Проверить logs
tail -f ./logs/auth-debug.log | grep "email_mandatory"

# Проверить Supabase JWT claims
curl -X POST /api/auth/supabase/login -H "Authorization: Bearer <supabase_jwt>"

Проблема: "Admin access denied"

Возможные причины:

  1. Email не в config/auth.yaml ADMIN_EMAILS
  2. Неправильный формат email в конфиге
  3. Email case sensitivity

Диагностика:

# Проверить конфиг админов
rg -n "ADMIN_EMAILS" ./config/

# Проверить email в lowercase
echo "user@domain.com" | tr '[:upper:]' '[:lower:]'

Проблема: "Supabase JWT verification failed"

Возможные причины:

  1. JWKS не загружен с Supabase
  2. JWT expired
  3. Неправильные Supabase настройки

Диагностика:

# Проверить Supabase connectivity
curl -X GET https://your-project.supabase.co/.well-known/jwks.json

# Проверить JWT payload
echo "<jwt_token>" | cut -d. -f2 | base64 -d | jq .

Связь с другими системами (Integration-Only)

Crypto2B Integration

  • Authenticated user email → депозитный адрес от Crypto2B
  • User ID из auth используется в crypto2b_transactions
  • См. также: Deposits Flow

Investment Integration

  • Auto-investment создается для authenticated user
  • Single strategy (10% APY) для всех пользователей
  • User ID из auth связывает investments

Admin Operations

  • Email-based admin access для всех операций
  • Fordefi управление требует admin authentication

Связанная документация

Security Checklist (Integration-Only)

При изменениях в authentication flow:

  • ✅ Email MANDATORY enforcement активен
  • ✅ Supabase JWT verification работает корректно
  • ❌ НЕТ wallet-based authentication
  • ✅ Админы только в config/auth.yaml
  • ✅ JWKS validation от Supabase
  • ✅ JWT expiration установлен правильно
  • ✅ Rate limiting активен
  • ✅ CORS настроен правильно
  • ✅ Логирование всех auth событий
  • ✅ Error handling не раскрывает sensitive data
  • ✅ Clean Architecture сохранена

Архитектурный контроль:

  • Handler содержит только HTTP logic
  • Service содержит бизнес-логику и validation
  • Repository содержит только data access
  • Middleware содержит только cross-cutting concerns