Files
core/docs/auth/system.md
Untone a4411e3c86
All checks were successful
Deploy on push / deploy (push) Successful in 5m47s
📚 Documentation Updates
- **🔍 Comprehensive authentication documentation refactoring**: Полная переработка документации аутентификации
  - Обновлена таблица содержания в README.md
  - Исправлены архитектурные диаграммы - токены хранятся только в Redis
  - Добавлены практические примеры кода для микросервисов
  - Консолидирована OAuth документация
2025-09-22 00:56:36 +03:00

374 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Система авторизации Discours Core
## 🎯 Обзор архитектуры
Модульная система авторизации с JWT токенами, Redis-сессиями и OAuth интеграцией. Построена на принципах разделения ответственности и высокой производительности.
```
auth/
├── tokens/ # 🎯 Система управления токенами
│ ├── sessions.py # JWT сессии с Redis
│ ├── verification.py # Одноразовые токены
│ ├── oauth.py # OAuth токены
│ ├── batch.py # Массовые операции
│ ├── monitoring.py # Мониторинг и статистика
│ ├── storage.py # Фасад для совместимости
│ ├── base.py # Базовые классы
│ └── types.py # Типы и константы
├── middleware.py # HTTP middleware
├── decorators.py # GraphQL декораторы
├── oauth.py # OAuth провайдеры
├── identity.py # Методы идентификации
├── jwtcodec.py # JWT кодек
├── validations.py # Валидация данных
├── credentials.py # Креденшиалы
├── exceptions.py # Исключения
└── utils.py # Утилиты
```
## 🎯 Система токенов
### SessionTokenManager
**Принцип работы:**
1. JWT токены с payload `{user_id, username, iat, exp}`
2. Redis хранение для отзыва и управления жизненным циклом
3. Поддержка множественных сессий на пользователя
4. Автоматическое обновление `last_activity` при активности
**Redis структура:**
```bash
session:{user_id}:{token} # hash с данными сессии
user_sessions:{user_id} # set с активными токенами
```
**Основные методы:**
```python
from auth.tokens.sessions import SessionTokenManager
sessions = SessionTokenManager()
# Создание сессии
token = await sessions.create_session(user_id, username=username)
# Проверка сессии
payload = await sessions.verify_session(token)
# Обновление сессии
new_token = await sessions.refresh_session(user_id, old_token)
# Отзыв сессии
await sessions.revoke_session_token(token)
# Получение всех сессий пользователя
user_sessions = await sessions.get_user_sessions(user_id)
```
### Типы токенов
| Тип | TTL | Назначение | Менеджер |
|-----|-----|------------|----------|
| `session` | 30 дней | JWT сессии пользователей | `SessionTokenManager` |
| `verification` | 1 час | Одноразовые токены подтверждения | `VerificationTokenManager` |
| `oauth_access` | 1 час | OAuth access токены | `OAuthTokenManager` |
| `oauth_refresh` | 30 дней | OAuth refresh токены | `OAuthTokenManager` |
### Менеджеры токенов
#### 1. **SessionTokenManager** - JWT сессии
```python
from auth.tokens.sessions import SessionTokenManager
sessions = SessionTokenManager()
# Создание сессии
token = await sessions.create_session(
user_id="123",
auth_data={"provider": "local"},
username="john_doe",
device_info={"ip": "192.168.1.1", "user_agent": "Mozilla/5.0"}
)
# Создание JWT токена сессии
token = await sessions.create_session_token(
user_id="123",
token_data={"username": "john_doe", "device_info": "..."}
)
# Проверка сессии (совместимость с TokenStorage)
payload = await sessions.verify_session(token)
# Возвращает: {"user_id": "123", "username": "john_doe", "iat": 1640995200, "exp": 1643587200}
# Валидация токена сессии
valid, data = await sessions.validate_session_token(token)
# Получение данных сессии
session_data = await sessions.get_session_data(token, user_id)
# Обновление сессии
new_token = await sessions.refresh_session(user_id, old_token, device_info)
# Отзыв сессии
await sessions.revoke_session_token(token)
# Отзыв всех сессий пользователя
revoked_count = await sessions.revoke_user_sessions(user_id)
# Получение всех сессий пользователя
user_sessions = await sessions.get_user_sessions(user_id)
```
#### 2. **VerificationTokenManager** - Одноразовые токены
```python
from auth.tokens.verification import VerificationTokenManager
verification = VerificationTokenManager()
# Создание токена подтверждения email
token = await verification.create_verification_token(
user_id="123",
verification_type="email_change",
data={"new_email": "new@example.com"},
ttl=3600 # 1 час
)
# Проверка токена
valid, data = await verification.validate_verification_token(token)
# Подтверждение (одноразовое использование)
confirmed_data = await verification.confirm_verification_token(token)
```
#### 3. **OAuthTokenManager** - OAuth токены
```python
from auth.tokens.oauth import OAuthTokenManager
oauth = OAuthTokenManager()
# Сохранение OAuth токенов
await oauth.store_oauth_tokens(
user_id="123",
provider="google",
access_token="ya29.a0AfH6SM...",
refresh_token="1//04...",
expires_in=3600,
additional_data={"scope": "read write"}
)
# Создание OAuth токена (внутренний метод)
token_key = await oauth._create_oauth_token(
user_id="123",
token_data={"token": "ya29.a0AfH6SM...", "provider": "google"},
ttl=3600,
provider="google",
token_type="oauth_access"
)
# Получение access токена
access_data = await oauth.get_token(user_id, "google", "oauth_access")
# Оптимизированное получение OAuth данных
oauth_data = await oauth._get_oauth_data_optimized("oauth_access", "123", "google")
# Отзыв OAuth токенов
await oauth.revoke_oauth_tokens(user_id, "google")
# Оптимизированный отзыв токена
revoked = await oauth._revoke_oauth_token_optimized("oauth_access", "123", "google")
# Отзыв всех OAuth токенов пользователя
revoked_count = await oauth.revoke_user_oauth_tokens(user_id, "oauth_access")
```
#### 4. **BatchTokenOperations** - Массовые операции
```python
from auth.tokens.batch import BatchTokenOperations
batch = BatchTokenOperations()
# Массовая проверка токенов
tokens = ["token1", "token2", "token3"]
results = await batch.batch_validate_tokens(tokens)
# {"token1": True, "token2": False, "token3": True}
# Валидация батча токенов (внутренний метод)
batch_results = await batch._validate_token_batch(tokens)
# Безопасное декодирование токена
payload = await batch._safe_decode_token(token)
# Массовый отзыв токенов
revoked_count = await batch.batch_revoke_tokens(tokens)
# Отзыв батча токенов (внутренний метод)
batch_revoked = await batch._revoke_token_batch(tokens)
# Очистка истекших токенов
cleaned_count = await batch.cleanup_expired_tokens()
```
#### 5. **TokenMonitoring** - Мониторинг
```python
from auth.tokens.monitoring import TokenMonitoring
monitoring = TokenMonitoring()
# Статистика токенов
stats = await monitoring.get_token_statistics()
# {
# "session_tokens": 150,
# "verification_tokens": 5,
# "oauth_access_tokens": 25,
# "oauth_refresh_tokens": 25,
# "memory_usage": 1048576
# }
# Подсчет ключей по паттерну (внутренний метод)
count = await monitoring._count_keys_by_pattern("session:*")
# Health check
health = await monitoring.health_check()
# {"status": "healthy", "redis_connected": True, "token_count": 205}
# Оптимизация памяти
optimization = await monitoring.optimize_memory_usage()
# {"cleaned_expired": 10, "memory_freed": 102400}
# Оптимизация структур данных (внутренний метод)
optimized = await monitoring._optimize_data_structures()
```
### TokenStorage (Фасад для совместимости)
```python
from auth.tokens.storage import TokenStorage
# Упрощенный API для основных операций
await TokenStorage.create_session(user_id, username=username)
await TokenStorage.verify_session(token)
await TokenStorage.refresh_session(user_id, old_token, device_info)
await TokenStorage.revoke_session(token)
```
## 🔧 Middleware и декораторы
### AuthMiddleware
```python
from auth.middleware import AuthMiddleware
# Автоматическая обработка токенов
middleware = AuthMiddleware()
# Извлечение токена из запроса
token = await extract_token_from_request(request)
# Проверка сессии
payload = await sessions.verify_session(token)
```
### GraphQL декораторы
```python
from auth.decorators import auth_required, permission_required
@auth_required
async def protected_resolver(info, **kwargs):
"""Требует авторизации"""
user = info.context.get('user')
return f"Hello, {user.username}!"
@permission_required("shout:create")
async def create_shout(info, input_data):
"""Требует права на создание публикаций"""
pass
```
## ORM модели
### Author (Пользователь)
```python
class Author:
id: int
email: str
name: str
slug: str
password: Optional[str] # bcrypt hash
pic: Optional[str] # URL аватара
bio: Optional[str]
email_verified: bool
phone_verified: bool
created_at: int
updated_at: int
last_seen: int
# OAuth данные в JSON формате
oauth: Optional[dict] # {"google": {"id": "123", "email": "user@gmail.com"}}
# Поля аутентификации
failed_login_attempts: int
account_locked_until: Optional[int]
```
### OAuth данные
OAuth данные хранятся в JSON поле `oauth` модели `Author`:
```python
# Формат oauth поля
{
"google": {
"id": "123456789",
"email": "user@gmail.com",
"name": "John Doe"
},
"github": {
"id": "456789",
"login": "johndoe",
"email": "user@github.com"
}
}
```
## ⚙️ Конфигурация
### Переменные окружения
```bash
# JWT настройки
JWT_SECRET=your_super_secret_key
JWT_EXPIRATION_HOURS=720 # 30 дней
# Redis подключение
REDIS_URL=redis://localhost:6379/0
# OAuth провайдеры
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
FACEBOOK_APP_ID=your_facebook_app_id
FACEBOOK_APP_SECRET=your_facebook_app_secret
VK_APP_ID=your_vk_app_id
VK_APP_SECRET=your_vk_app_secret
YANDEX_CLIENT_ID=your_yandex_client_id
YANDEX_CLIENT_SECRET=your_yandex_client_secret
# Session cookies
SESSION_COOKIE_NAME=session_token
SESSION_COOKIE_SECURE=true
SESSION_COOKIE_HTTPONLY=true
SESSION_COOKIE_SAMESITE=lax
SESSION_COOKIE_MAX_AGE=2592000 # 30 дней
# Frontend
FRONTEND_URL=https://yourdomain.com
```
## Производительность
### Оптимизации Redis
- **Pipeline операции** для атомарности
- **Batch обработка** токенов (100-1000 за раз)
- **SCAN** вместо KEYS для безопасности
- **TTL** автоматическая очистка
### Кэширование
- **@lru_cache** для часто используемых ключей
- **Connection pooling** для Redis
- **JWT decode caching** в middleware