""" Авторизация для API RAG сервиса. Поддерживает авторизацию через API ключ в заголовке X-API-Key. """ import logging from typing import Annotated, Optional from fastapi import Depends, HTTPException, Security, status from fastapi.security import APIKeyHeader from app.config import Settings, get_settings logger = logging.getLogger(__name__) # Схема авторизации через заголовок api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False) async def verify_api_key( api_key: Annotated[Optional[str], Security(api_key_header)], settings: Annotated[Settings, Depends(get_settings)], ) -> bool: """ Проверяет API ключ из заголовка запроса. Args: api_key: Ключ из заголовка X-API-Key settings: Настройки приложения Returns: True если авторизация успешна Raises: HTTPException: Если ключ неверный или отсутствует """ # Если API ключ не настроен и разрешены запросы без авторизации if settings.api_key is None: if settings.allow_no_auth: logger.debug("Авторизация отключена (RAG_ALLOW_NO_AUTH=true)") return True else: logger.warning("API ключ не настроен! Установите RAG_API_KEY") # В продакшене без ключа сервис не должен работать raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="API ключ не настроен на сервере", ) # Проверяем ключ if api_key is None: logger.warning("Запрос без API ключа") raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="API ключ не предоставлен. Используйте заголовок X-API-Key", headers={"WWW-Authenticate": "ApiKey"}, ) if api_key != settings.api_key: logger.warning("Неверный API ключ") raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Неверный API ключ", ) return True # Dependency для использования в роутах AuthDep = Annotated[bool, Depends(verify_api_key)]