diff --git a/auth/handler.py b/auth/handler.py index 1a9858f6..9f56fe42 100644 --- a/auth/handler.py +++ b/auth/handler.py @@ -44,12 +44,6 @@ class EnhancedGraphQLHTTPHandler(GraphQLHTTPHandler): except Exception as e: logger.debug(f"[graphql] Ошибка при получении заголовков: {e}") - logger.debug(f"[graphql] Заголовки в get_context_for_request: {list(headers.keys())}") - if "authorization" in headers: - logger.debug(f"[graphql] Authorization header найден: {headers['authorization'][:50]}...") - else: - logger.debug("[graphql] Authorization header НЕ найден") - # Получаем стандартный контекст от базового класса context = await super().get_context_for_request(request, data) @@ -67,15 +61,6 @@ class EnhancedGraphQLHTTPHandler(GraphQLHTTPHandler): auth_cred: Any | None = request.scope.get("auth") context["auth"] = auth_cred # Безопасно логируем информацию о типе объекта auth - logger.debug(f"[graphql] Добавлены данные авторизации в контекст из scope: {type(auth_cred).__name__}") - - # Проверяем, есть ли токен в auth_cred - if auth_cred is not None and hasattr(auth_cred, "token") and auth_cred.token: - token_val = auth_cred.token - token_len = len(token_val) if hasattr(token_val, "__len__") else 0 - logger.debug(f"[graphql] Токен найден в auth_cred: {token_len}") - else: - logger.debug("[graphql] Токен НЕ найден в auth_cred") # Добавляем author_id в контекст для RBAC author_id = None @@ -89,16 +74,8 @@ class EnhancedGraphQLHTTPHandler(GraphQLHTTPHandler): try: author_id_int = int(str(author_id).strip()) context["author"] = {"id": author_id_int} - logger.debug(f"[graphql] Добавлен author_id в контекст: {author_id_int}") except (ValueError, TypeError) as e: logger.error(f"[graphql] Ошибка преобразования author_id {author_id}: {e}") context["author"] = {"id": author_id} - logger.debug(f"[graphql] Добавлен author_id как строка: {author_id}") - else: - logger.debug("[graphql] author_id не найден в auth_cred") - else: - logger.debug("[graphql] Данные авторизации НЕ найдены в scope") - - logger.debug("[graphql] Подготовлен расширенный контекст для запроса") return context diff --git a/auth/middleware.py b/auth/middleware.py index 333ddee5..f2b3ee4b 100644 --- a/auth/middleware.py +++ b/auth/middleware.py @@ -28,7 +28,6 @@ from settings import ( SESSION_TOKEN_HEADER, ) from storage.db import local_session -from storage.redis import redis as redis_adapter from utils.logger import root_logger as logger ADMIN_EMAILS = ADMIN_EMAILS_LIST.split(",") @@ -82,7 +81,6 @@ class AuthMiddleware: async def authenticate_user(self, token: str) -> tuple[AuthCredentials, AuthenticatedUser | UnauthenticatedUser]: """Аутентифицирует пользователя по токену""" if not token: - logger.debug("[auth.authenticate] Токен отсутствует") return AuthCredentials( author_id=None, scopes={}, logged_in=False, error_message="no token", email=None, token=None ), UnauthenticatedUser() @@ -202,24 +200,6 @@ class AuthMiddleware: scope_headers = scope.get("headers", []) if scope_headers: headers.update({k.decode("utf-8").lower(): v.decode("utf-8") for k, v in scope_headers}) - logger.debug(f"[middleware] Получены заголовки из scope: {len(headers)}") - # Проверяем наличие authorization заголовка - if "authorization" in headers: - logger.debug(f"[middleware] Authorization заголовок найден: {headers['authorization'][:50]}...") - else: - logger.debug("[middleware] Authorization заголовок НЕ найден в scope headers") - else: - logger.debug("[middleware] Заголовки scope отсутствуют") - - # Логируем все заголовки для диагностики - logger.debug(f"[middleware] Все заголовки: {list(headers.keys())}") - - # Логируем конкретные заголовки для диагностики - auth_header_value = headers.get("authorization", "") - logger.debug(f"[middleware] Authorization header: {auth_header_value[:50]}...") - - session_token_value = headers.get(SESSION_TOKEN_HEADER.lower(), "") - logger.debug(f"[middleware] {SESSION_TOKEN_HEADER} header: {session_token_value[:50]}...") # Используем тот же механизм получения токена, что и в декораторе token = None @@ -227,100 +207,31 @@ class AuthMiddleware: # 0. Проверяем сохраненный токен в scope (приоритет) if "auth_token" in scope: token = scope["auth_token"] - logger.debug(f"[middleware] Токен получен из scope.auth_token: {len(token)}") - else: - logger.debug("[middleware] scope.auth_token НЕ найден") - - # Стандартная система сессий уже обрабатывает кэширование - # Дополнительной проверки Redis кэша не требуется - - # Отладка: детальная информация о запросе без Authorization - if not token: - # Проверяем, есть ли активные сессии в Redis - try: - # Получаем все активные сессии - session_keys = await redis_adapter.keys("session:*") - logger.debug(f"[middleware] Найдено активных сессий в Redis: {len(session_keys)}") - - if session_keys: - # Пытаемся найти токен через активные сессии - for session_key in session_keys[:3]: # Проверяем первые 3 сессии - try: - session_data = await redis_adapter.hgetall(session_key) - if session_data: - logger.debug(f"[middleware] Найдена активная сессия: {session_key}") - # Извлекаем user_id из ключа сессии - user_id = ( - session_key.decode("utf-8").split(":")[1] - if isinstance(session_key, bytes) - else session_key.split(":")[1] - ) - logger.debug(f"[middleware] User ID из сессии: {user_id}") - break - except Exception as e: - logger.debug(f"[middleware] Ошибка чтения сессии {session_key}: {e}") - else: - logger.debug("[middleware] Активных сессий в Redis не найдено") - - except Exception as e: - logger.debug(f"[middleware] Ошибка проверки сессий: {e}") # 1. Проверяем заголовок Authorization if not token: auth_header = headers.get("authorization", "") if auth_header: - if auth_header.startswith("Bearer "): - token = auth_header[7:].strip() - logger.debug(f"[middleware] Токен получен из заголовка Authorization: {len(token)}") - else: - token = auth_header.strip() - logger.debug(f"[middleware] Прямой токен получен из заголовка Authorization: {len(token)}") + token = auth_header[7:].strip() if auth_header.startswith("Bearer ") else auth_header.strip() # 2. Проверяем основной заголовок авторизации, если Authorization не найден if not token: auth_header = headers.get(SESSION_TOKEN_HEADER.lower(), "") if auth_header: - if auth_header.startswith("Bearer "): - token = auth_header[7:].strip() - logger.debug(f"[middleware] Токен получен из заголовка {SESSION_TOKEN_HEADER}: {len(token)}") - else: - token = auth_header.strip() - logger.debug(f"[middleware] Прямой токен получен из заголовка {SESSION_TOKEN_HEADER}: {len(token)}") + token = auth_header[7:].strip() if auth_header.startswith("Bearer ") else auth_header.strip() # 3. Проверяем cookie if not token: cookies = headers.get("cookie", "") - logger.debug(f"[middleware] Проверяем cookies: {cookies[:100]}...") - logger.debug(f"[middleware] Ищем cookie с именем: '{SESSION_COOKIE_NAME}'") - - # 🔍 Диагностика cookies (только для debug уровня) - if not cookies: - logger.debug("[middleware] Cookie заголовок отсутствует") - logger.debug(f"[middleware] Доступные заголовки: {list(headers.keys())}") - # 💋 OAuth не использует cookies - это нормальное поведение - logger.debug("[middleware] OAuth система работает без cookies - токены передаются через заголовки") - - cookie_items = cookies.split(";") - found_cookies = [] - for item in cookie_items: - if "=" in item: - name, value = item.split("=", 1) - cookie_name = name.strip() - found_cookies.append(cookie_name) - if cookie_name == SESSION_COOKIE_NAME: - token = value.strip() - logger.debug( - f"[middleware] ✅ Токен получен из cookie {SESSION_COOKIE_NAME}: {len(token)} символов" - ) - break - logger.debug(f"[middleware] Найденные cookies: {found_cookies}") - if not token: - logger.debug(f"[middleware] ❌ Cookie '{SESSION_COOKIE_NAME}' не найден среди: {found_cookies}") - - if token: - logger.debug(f"[middleware] Токен найден: {len(token)} символов") - else: - logger.debug("[middleware] Токен не найден") + if cookies: + cookie_items = cookies.split(";") + for item in cookie_items: + if "=" in item: + name, value = item.split("=", 1) + cookie_name = name.strip() + if cookie_name == SESSION_COOKIE_NAME: + token = value.strip() + break # Аутентифицируем пользователя auth, user = await self.authenticate_user(token or "") @@ -332,21 +243,12 @@ class AuthMiddleware: # Сохраняем токен в scope для использования в последующих запросах if token: scope["auth_token"] = token - logger.debug(f"[middleware] Токен сохранен в scope.auth_token: {len(token)}") - logger.debug(f"[middleware] Пользователь аутентифицирован: {user.is_authenticated}") - - # Токен уже сохранен в стандартной системе сессий через SessionTokenManager - # Дополнительного кэширования не требуется - logger.debug("[middleware] Токен обработан стандартной системой сессий") - else: - logger.debug("[middleware] Токен не найден, пользователь неаутентифицирован") await self.app(scope, receive, send) def set_context(self, context) -> None: """Сохраняет ссылку на контекст GraphQL запроса""" self._context = context - logger.debug(f"[middleware] Установлен контекст GraphQL: {bool(context)}") def set_cookie(self, key: str, value: str, **options: Any) -> None: """ @@ -363,7 +265,6 @@ class AuthMiddleware: if self._context and "response" in self._context and hasattr(self._context["response"], "set_cookie"): try: self._context["response"].set_cookie(key, value, **options) - logger.debug(f"[middleware] Установлена cookie {key} через response") success = True except Exception as e: logger.error(f"[middleware] Ошибка при установке cookie {key} через response: {e!s}") @@ -372,7 +273,6 @@ class AuthMiddleware: if not success and hasattr(self, "_response") and self._response and hasattr(self._response, "set_cookie"): try: self._response.set_cookie(key, value, **options) - logger.debug(f"[middleware] Установлена cookie {key} через _response") success = True except Exception as e: logger.error(f"[middleware] Ошибка при установке cookie {key} через _response: {e!s}") @@ -390,7 +290,6 @@ class AuthMiddleware: if self._context and "response" in self._context and hasattr(self._context["response"], "delete_cookie"): try: self._context["response"].delete_cookie(key, **options) - logger.debug(f"[middleware] Удалена cookie {key} через response") success = True except Exception as e: logger.error(f"[middleware] Ошибка при удалении cookie {key} через response: {e!s}") @@ -399,7 +298,6 @@ class AuthMiddleware: if not success and hasattr(self, "_response") and self._response and hasattr(self._response, "delete_cookie"): try: self._response.delete_cookie(key, **options) - logger.debug(f"[middleware] Удалена cookie {key} через _response") success = True except Exception as e: logger.error(f"[middleware] Ошибка при удалении cookie {key} через _response: {e!s}") @@ -427,9 +325,6 @@ class AuthMiddleware: # Проверяем наличие response в контексте if "response" not in context or not context["response"]: context["response"] = JSONResponse({}) - logger.debug("[middleware] Создан новый response объект в контексте GraphQL") - - logger.debug("[middleware] GraphQL resolve: контекст подготовлен, добавлены расширения для работы с cookie") return await next_resolver(root, info, *args, **kwargs) except Exception as e: @@ -457,16 +352,8 @@ class AuthMiddleware: data = await request.json() op_name = data.get("operationName", "").lower() - # 💋 OAuth НЕ использует cookies - токены передаются только через заголовки/localStorage - # Убираем автоматическую установку cookies для login/refreshtoken/getSession - if op_name in ["login", "refreshtoken", "getsession"]: - logger.debug(f"[graphql_handler] Операция {op_name}: токены передаются БЕЗ cookies") - logger.debug( - "[graphql_handler] Фронтенд должен извлечь токен из ответа и управлять им самостоятельно" - ) - # Если это операция logout, удаляем cookie - elif op_name == "logout": + if op_name == "logout": response.delete_cookie( key=SESSION_COOKIE_NAME, secure=SESSION_COOKIE_SECURE, @@ -474,9 +361,8 @@ class AuthMiddleware: samesite=SESSION_COOKIE_SAMESITE if SESSION_COOKIE_SAMESITE in ["strict", "lax", "none"] else "none", - domain=SESSION_COOKIE_DOMAIN, # ✅ КРИТИЧНО: тот же domain что при установке + domain=SESSION_COOKIE_DOMAIN, ) - logger.debug(f"[graphql_handler] Удалена cookie {SESSION_COOKIE_NAME} для операции {op_name}") except Exception as e: logger.error(f"[process_result] Ошибка при обработке POST запроса: {e!s}") diff --git a/resolvers/reader.py b/resolvers/reader.py index 5985cde1..0ac51d9f 100644 --- a/resolvers/reader.py +++ b/resolvers/reader.py @@ -342,14 +342,14 @@ def get_shouts_with_links( if has_field(info, "main_topic") or force_topics: main_topic = None if hasattr(row, "main_topic"): - logger.debug(f"Raw main_topic for shout#{shout_id}: {row.main_topic}") + # logger.debug(f"Raw main_topic for shout#{shout_id}: {row.main_topic}") main_topic = ( orjson.loads(row.main_topic) if isinstance(row.main_topic, str) else row.main_topic ) - logger.debug(f"Parsed main_topic for shout#{shout_id}: {main_topic}") + # logger.debug(f"Parsed main_topic for shout#{shout_id}: {main_topic}") if not main_topic and topics and len(topics) > 0: - logger.info(f"No main_topic found for shout#{shout_id}, using first topic from list") + # logger.info(f"No main_topic found for shout#{shout_id}, using first topic from list") main_topic = { "id": topics[0]["id"], "title": topics[0]["title"], @@ -365,7 +365,7 @@ def get_shouts_with_links( "is_main": True, } shout_dict["main_topic"] = main_topic - logger.debug(f"Final main_topic for shout#{shout_id}: {main_topic}") + # logger.debug(f"Final main_topic for shout#{shout_id}: {main_topic}") if has_field(info, "authors") and hasattr(row, "authors"): authors_data = orjson.loads(row.authors) if isinstance(row.authors, str) else row.authors