Files

2.6 KiB

Безопасность

Базовые требования

  • .env — всегда в .gitignore. Никогда не коммитить.
  • JWT: алгоритм HS256, access_token = 60 минут, refresh_token = 30 дней
  • Пароли: bcrypt через passlib
  • Pydantic валидация на всех входах
  • RBAC: роли user, admin

Аутентификация

JWT

# app/core/security.py

def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=60))
    to_encode.update({"exp": expire, "type": "access"})
    return jwt.encode(to_encode, settings.jwt_secret_key, algorithm=settings.jwt_algorithm)

def decode_token(token: str) -> dict[str, Any] | None:
    try:
        return jwt.decode(token, settings.jwt_secret_key, algorithms=[settings.jwt_algorithm])
    except JWTError:
        return None

Password hashing

from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def verify_password(plain: str, hashed: str) -> bool:
    return pwd_context.verify(plain, hashed)

RBAC

Роль Права
user Базовые: CRUD своих данных, запуск анализа
admin (is_superuser) Управление пользователями, просмотр логов, системные настройки

Проверка прав:

async def require_admin(user: Annotated[User, Depends(get_current_user)]) -> User:
    if not user.is_superuser:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required")
    return user

Sensitive Data

Никогда не логировать:

  • Пароли (даже хэш)
  • JWT токены
  • API keys и секреты
  • Email в открытом виде (только user_id)

Маскировать в логах:


[ASK] Вопросы по безопасности

  • Нужен ли audit log? (рекомендуется для production)
  • Нужно ли шифрование данных в покое? (да, если хранятся персональные данные)
  • Нужен ли rate limiting? (да, для production)
  • Нужен ли CORS? (да, если фронтенд на другом домене)
  • Нужен ли CSRF? (нет, если используем JWT в Bearer header)