# 🔧 Auth API Reference ## 🎯 Обзор Полный справочник по API системы аутентификации с примерами кода и использования. ## 📚 Token Managers ### SessionTokenManager ```python from auth.tokens.sessions import SessionTokenManager sessions = SessionTokenManager() ``` #### Методы ##### `create_session(user_id, auth_data=None, username=None, device_info=None)` Создает новую сессию для пользователя. **Параметры:** - `user_id` (str): ID пользователя - `auth_data` (dict, optional): Данные аутентификации - `username` (str, optional): Имя пользователя - `device_info` (dict, optional): Информация об устройстве **Возвращает:** `str` - JWT токен **Пример:** ```python token = await sessions.create_session( user_id="123", username="john_doe", device_info={"ip": "192.168.1.1", "user_agent": "Mozilla/5.0"} ) ``` ##### `verify_session(token)` Проверяет валидность JWT токена и Redis сессии. **Параметры:** - `token` (str): JWT токен **Возвращает:** `dict | None` - Payload токена или None **Пример:** ```python payload = await sessions.verify_session(token) if payload: user_id = payload.get("user_id") username = payload.get("username") ``` ##### `validate_session_token(token)` Валидирует токен сессии с дополнительными проверками. **Параметры:** - `token` (str): JWT токен **Возвращает:** `tuple[bool, dict]` - (валидность, данные) **Пример:** ```python valid, data = await sessions.validate_session_token(token) if valid: print(f"Session valid for user: {data.get('user_id')}") ``` ##### `get_session_data(token, user_id)` Получает данные сессии из Redis. **Параметры:** - `token` (str): JWT токен - `user_id` (str): ID пользователя **Возвращает:** `dict | None` - Данные сессии **Пример:** ```python session_data = await sessions.get_session_data(token, user_id) if session_data: last_activity = session_data.get("last_activity") ``` ##### `refresh_session(user_id, old_token, device_info=None)` Обновляет сессию пользователя. **Параметры:** - `user_id` (str): ID пользователя - `old_token` (str): Старый JWT токен - `device_info` (dict, optional): Информация об устройстве **Возвращает:** `str` - Новый JWT токен **Пример:** ```python new_token = await sessions.refresh_session( user_id="123", old_token=old_token, device_info={"ip": "192.168.1.1"} ) ``` ##### `revoke_session_token(token)` Отзывает конкретный токен сессии. **Параметры:** - `token` (str): JWT токен **Возвращает:** `bool` - Успешность операции **Пример:** ```python revoked = await sessions.revoke_session_token(token) if revoked: print("Session revoked successfully") ``` ##### `get_user_sessions(user_id)` Получает все активные сессии пользователя. **Параметры:** - `user_id` (str): ID пользователя **Возвращает:** `list[dict]` - Список сессий **Пример:** ```python user_sessions = await sessions.get_user_sessions("123") for session in user_sessions: print(f"Token: {session['token'][:20]}...") print(f"Last activity: {session['last_activity']}") ``` ##### `revoke_user_sessions(user_id)` Отзывает все сессии пользователя. **Параметры:** - `user_id` (str): ID пользователя **Возвращает:** `int` - Количество отозванных сессий **Пример:** ```python revoked_count = await sessions.revoke_user_sessions("123") print(f"Revoked {revoked_count} sessions") ``` ### OAuthTokenManager ```python from auth.tokens.oauth import OAuthTokenManager oauth = OAuthTokenManager() ``` #### Методы ##### `store_oauth_tokens(user_id, provider, access_token, refresh_token=None, expires_in=3600, additional_data=None)` Сохраняет OAuth токены в Redis. **Параметры:** - `user_id` (str): ID пользователя - `provider` (str): OAuth провайдер (google, github, etc.) - `access_token` (str): Access токен - `refresh_token` (str, optional): Refresh токен - `expires_in` (int): Время жизни в секундах - `additional_data` (dict, optional): Дополнительные данные **Пример:** ```python 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"} ) ``` ##### `get_token(user_id, provider, token_type)` Получает OAuth токен. **Параметры:** - `user_id` (str): ID пользователя - `provider` (str): OAuth провайдер - `token_type` (str): Тип токена ("oauth_access" или "oauth_refresh") **Возвращает:** `dict | None` - Данные токена **Пример:** ```python access_data = await oauth.get_token("123", "google", "oauth_access") if access_data: token = access_data["token"] expires_in = access_data.get("expires_in") ``` ##### `revoke_oauth_tokens(user_id, provider)` Отзывает OAuth токены провайдера. **Параметры:** - `user_id` (str): ID пользователя - `provider` (str): OAuth провайдер **Возвращает:** `bool` - Успешность операции **Пример:** ```python revoked = await oauth.revoke_oauth_tokens("123", "google") if revoked: print("OAuth tokens revoked") ``` ### BatchTokenOperations ```python from auth.tokens.batch import BatchTokenOperations batch = BatchTokenOperations() ``` #### Методы ##### `batch_validate_tokens(tokens)` Массовая валидация токенов. **Параметры:** - `tokens` (list[str]): Список JWT токенов **Возвращает:** `dict[str, bool]` - Результаты валидации **Пример:** ```python tokens = ["token1", "token2", "token3"] results = await batch.batch_validate_tokens(tokens) # {"token1": True, "token2": False, "token3": True} for token, is_valid in results.items(): print(f"Token {token[:10]}... is {'valid' if is_valid else 'invalid'}") ``` ##### `batch_revoke_tokens(tokens)` Массовый отзыв токенов. **Параметры:** - `tokens` (list[str]): Список JWT токенов **Возвращает:** `int` - Количество отозванных токенов **Пример:** ```python revoked_count = await batch.batch_revoke_tokens(tokens) print(f"Revoked {revoked_count} tokens") ``` ##### `cleanup_expired_tokens()` Очистка истекших токенов. **Возвращает:** `int` - Количество очищенных токенов **Пример:** ```python cleaned_count = await batch.cleanup_expired_tokens() print(f"Cleaned {cleaned_count} expired tokens") ``` ### TokenMonitoring ```python from auth.tokens.monitoring import TokenMonitoring monitoring = TokenMonitoring() ``` #### Методы ##### `get_token_statistics()` Получает статистику токенов. **Возвращает:** `dict` - Статистика системы **Пример:** ```python stats = await monitoring.get_token_statistics() print(f"Active sessions: {stats['session_tokens']}") print(f"OAuth tokens: {stats['oauth_access_tokens']}") print(f"Memory usage: {stats['memory_usage'] / 1024 / 1024:.2f} MB") ``` ##### `health_check()` Проверка здоровья системы токенов. **Возвращает:** `dict` - Статус системы **Пример:** ```python health = await monitoring.health_check() if health["status"] == "healthy": print("Token system is healthy") print(f"Redis connected: {health['redis_connected']}") else: print(f"System unhealthy: {health.get('error')}") ``` ##### `optimize_memory_usage()` Оптимизация использования памяти. **Возвращает:** `dict` - Результаты оптимизации **Пример:** ```python results = await monitoring.optimize_memory_usage() print(f"Cleaned expired: {results['cleaned_expired']}") print(f"Memory freed: {results['memory_freed']} bytes") ``` ## 🛠️ Utility Functions ### Auth Utils ```python from auth.utils import ( extract_token_from_request, get_auth_token, get_auth_token_from_context, get_safe_headers, get_user_data_by_token ) ``` #### `extract_token_from_request(request)` Извлекает токен из HTTP запроса. **Параметры:** - `request`: HTTP запрос (FastAPI, Starlette, etc.) **Возвращает:** `str | None` - JWT токен или None **Пример:** ```python token = await extract_token_from_request(request) if token: print(f"Found token: {token[:20]}...") ``` #### `get_auth_token(request)` Расширенное извлечение токена с логированием. **Параметры:** - `request`: HTTP запрос **Возвращает:** `str | None` - JWT токен или None **Пример:** ```python token = await get_auth_token(request) if token: # Токен найден и залогирован pass ``` #### `get_auth_token_from_context(info)` Извлечение токена из GraphQL контекста. **Параметры:** - `info`: GraphQL Info объект **Возвращает:** `str | None` - JWT токен или None **Пример:** ```python @auth_required async def protected_resolver(info, **kwargs): token = await get_auth_token_from_context(info) # Используем токен для дополнительных проверок ``` #### `get_safe_headers(request)` Безопасное получение заголовков запроса. **Параметры:** - `request`: HTTP запрос **Возвращает:** `dict[str, str]` - Словарь заголовков **Пример:** ```python headers = get_safe_headers(request) auth_header = headers.get("authorization", "") user_agent = headers.get("user-agent", "") ``` #### `get_user_data_by_token(token)` Получение данных пользователя по токену. **Параметры:** - `token` (str): JWT токен **Возвращает:** `dict | None` - Данные пользователя **Пример:** ```python user_data = await get_user_data_by_token(token) if user_data: print(f"User: {user_data['username']}") print(f"ID: {user_data['user_id']}") ``` ## 🎭 Decorators ### GraphQL Decorators ```python from auth.decorators import auth_required, permission_required ``` #### `@auth_required` Требует авторизации для выполнения resolver'а. **Пример:** ```python @auth_required async def get_user_profile(info, **kwargs): """Получение профиля пользователя""" user = info.context.get('user') return { "id": user.id, "username": user.username, "email": user.email } ``` #### `@permission_required(permission)` Требует конкретного разрешения. **Параметры:** - `permission` (str): Название разрешения **Пример:** ```python @auth_required @permission_required("shout:create") async def create_shout(info, input_data): """Создание публикации""" user = info.context.get('user') shout = Shout( title=input_data['title'], content=input_data['content'], author_id=user.id ) return shout ``` ## 🔧 Middleware ### AuthMiddleware ```python from auth.middleware import AuthMiddleware middleware = AuthMiddleware() ``` #### Методы ##### `authenticate_user(request)` Аутентификация пользователя из запроса. **Параметры:** - `request`: HTTP запрос **Возвращает:** `dict | None` - Данные пользователя **Пример:** ```python user_data = await middleware.authenticate_user(request) if user_data: request.user = user_data ``` ##### `set_cookie(response, token)` Установка httpOnly cookie с токеном. **Параметры:** - `response`: HTTP ответ - `token` (str): JWT токен **Пример:** ```python await middleware.set_cookie(response, token) ``` ##### `delete_cookie(response)` Удаление cookie с токеном. **Параметры:** - `response`: HTTP ответ **Пример:** ```python await middleware.delete_cookie(response) ``` ## 🔒 Error Handling ### Исключения ```python from auth.exceptions import ( AuthenticationError, InvalidTokenError, TokenExpiredError, OAuthError ) ``` #### `AuthenticationError` Базовое исключение аутентификации. **Пример:** ```python try: payload = await sessions.verify_session(token) if not payload: raise AuthenticationError("Invalid session token") except AuthenticationError as e: return {"error": str(e), "status": 401} ``` #### `InvalidTokenError` Невалидный токен. **Пример:** ```python try: valid, data = await sessions.validate_session_token(token) if not valid: raise InvalidTokenError("Token validation failed") except InvalidTokenError as e: return {"error": str(e), "status": 401} ``` #### `TokenExpiredError` Истекший токен. **Пример:** ```python try: # Проверка токена pass except TokenExpiredError as e: return {"error": "Token expired", "status": 401} ``` ## 📊 Response Formats ### Успешные ответы ```python # Успешная аутентификация { "authenticated": True, "user_id": "123", "username": "john_doe", "expires_at": 1640995200 } # Статистика токенов { "session_tokens": 150, "oauth_access_tokens": 25, "oauth_refresh_tokens": 25, "verification_tokens": 5, "memory_usage": 1048576 } # Health check { "status": "healthy", "redis_connected": True, "token_count": 205, "timestamp": 1640995200 } ``` ### Ошибки ```python # Ошибка аутентификации { "authenticated": False, "error": "Invalid or expired token", "status": 401 } # Ошибка системы { "status": "error", "error": "Redis connection failed", "timestamp": 1640995200 } ``` ## 🧪 Testing Helpers ### Mock Utilities ```python from unittest.mock import AsyncMock, patch # Mock SessionTokenManager @patch('auth.tokens.sessions.SessionTokenManager') async def test_auth(mock_sessions): mock_sessions.return_value.verify_session.return_value = { "user_id": "123", "username": "testuser" } # Ваш тест здесь pass # Mock Redis @patch('storage.redis.redis') async def test_redis_operations(mock_redis): mock_redis.get.return_value = b'{"user_id": "123"}' mock_redis.exists.return_value = True # Ваш тест здесь pass ``` ### Test Fixtures ```python import pytest @pytest.fixture async def auth_token(): """Фикстура для создания тестового токена""" sessions = SessionTokenManager() return await sessions.create_session( user_id="test_user", username="testuser" ) @pytest.fixture async def authenticated_request(auth_token): """Фикстура для аутентифицированного запроса""" mock_request = AsyncMock() mock_request.headers = {"authorization": f"Bearer {auth_token}"} return mock_request ```