72 lines
2.5 KiB
Python
72 lines
2.5 KiB
Python
"""
|
||
Авторизация для 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)]
|