From f2e144e9ca5ee314e3ae8ea9923e3d4aa95ac1b3 Mon Sep 17 00:00:00 2001 From: Fedor Date: Fri, 27 Feb 2026 10:33:07 +0300 Subject: [PATCH] =?UTF-8?q?Session:=20=D0=B4=D1=83=D0=B1=D0=BB=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D1=81=D0=B5=D1=81=D1=81=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B2=D0=BE=20=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9=20Redis=20=D0=B4=D0=BB=D1=8F=20=D0=B4=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=83=D0=BF=D0=B0=20=D0=B8=D0=B7=20n8n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - backend/app/api/session.py: при записи сессии в локальный Redis (6383) теперь также дублируем те же ключи в внешний Redis (REDIS_HOST/REDIS_PORT) через redis_service.client. - Дублируются оба вида ключей: - session:{channel}:{channel_user_id} - session:{session_token} - Ошибки внешнего Redis не ломают авторизацию: при недоступности — warning в логах. --- ...T_MSG_SESSION_DUPLICATE_EXTERNAL_REDIS.txt | 8 +++++ backend/app/api/session.py | 30 ++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 COMMIT_MSG_SESSION_DUPLICATE_EXTERNAL_REDIS.txt diff --git a/COMMIT_MSG_SESSION_DUPLICATE_EXTERNAL_REDIS.txt b/COMMIT_MSG_SESSION_DUPLICATE_EXTERNAL_REDIS.txt new file mode 100644 index 0000000..6cceb7f --- /dev/null +++ b/COMMIT_MSG_SESSION_DUPLICATE_EXTERNAL_REDIS.txt @@ -0,0 +1,8 @@ +Session: дублировать сессии во внешний Redis для доступа из n8n + +- backend/app/api/session.py: при записи сессии в локальный Redis (6383) теперь также дублируем те же ключи + в внешний Redis (REDIS_HOST/REDIS_PORT) через redis_service.client. +- Дублируются оба вида ключей: + - session:{channel}:{channel_user_id} + - session:{session_token} +- Ошибки внешнего Redis не ломают авторизацию: при недоступности — warning в логах. diff --git a/backend/app/api/session.py b/backend/app/api/session.py index 179aafa..6f1acf0 100644 --- a/backend/app/api/session.py +++ b/backend/app/api/session.py @@ -16,6 +16,8 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel import redis.asyncio as redis +from ..services.redis_service import redis_service + logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v1/session", tags=["session"]) @@ -59,10 +61,20 @@ async def set_session_by_channel_user( "verified_at": datetime.utcnow().isoformat(), } ttl = SESSION_BY_CHANNEL_TTL_HOURS * 3600 if SESSION_BY_CHANNEL_TTL_HOURS else None + body = json.dumps(payload) if ttl: - await redis_client.setex(key, ttl, json.dumps(payload)) + await redis_client.setex(key, ttl, body) else: - await redis_client.set(key, json.dumps(payload)) + await redis_client.set(key, body) + # Дублируем сессию в внешний Redis, чтобы n8n мог читать по тем же ключам + try: + if redis_service.client: + if ttl: + await redis_service.client.setex(key, ttl, body) + else: + await redis_service.client.set(key, body) + except Exception as e: + logger.warning("Не удалось продублировать сессию в внешний Redis (channel): %s", e) logger.info("Сессия записана: %s, unified_id=%s", key, payload.get("unified_id")) @@ -94,10 +106,20 @@ async def set_session_by_token(session_token: str, data: Dict[str, Any]) -> None "verified_at": datetime.utcnow().isoformat(), } ttl = SESSION_BY_CHANNEL_TTL_HOURS * 3600 if SESSION_BY_CHANNEL_TTL_HOURS else None + body = json.dumps(payload) if ttl: - await redis_client.setex(key, ttl, json.dumps(payload)) + await redis_client.setex(key, ttl, body) else: - await redis_client.set(key, json.dumps(payload)) + await redis_client.set(key, body) + # Дублируем сессию по токену в внешний Redis для доступа из n8n + try: + if redis_service.client: + if ttl: + await redis_service.client.setex(key, ttl, body) + else: + await redis_service.client.set(key, body) + except Exception as e: + logger.warning("Не удалось продублировать сессию в внешний Redis (token): %s", e) class SessionVerifyRequest(BaseModel):