Skip to content

Глава 6.5: Основы безопасности API

Время изучения: 45 минут


1. Безопасность API: Многоуровневая оборона станции

Представьте, что ваша космическая станция (API) находится во враждебном секторе космоса. Одного силового поля (аутентификации) недостаточно. Вам нужна комплексная система обороны:

  • Щиты (HTTPS): Шифрование всего трафика.
  • Датчики аномалий (Rate Limiting): Защита от слишком частых запросов.
  • Внутренние переборки (Авторизация): Разделение прав доступа.
  • Проверка грузов (Валидация): Не доверять никаким входящим данным.
  • Секретный сейф (Переменные окружения): Безопасное хранение ключей.

Давайте настроим каждый из этих уровней.


2. Щиты: Всегда используйте HTTPS

Что это? HTTPS (HyperText Transfer Protocol Secure) — это версия протокола HTTP, которая шифрует все данные между клиентом и сервером. Без него любой, кто "слушает" сеть (например, в публичном Wi-Fi), может перехватить логины, пароли и токены.

Как реализовать?

  • На продакшене — обязательно. При развертывании вашего API на реальном сервере (Heroku, DigitalOcean, etc.) настройте веб-сервер (Nginx, Apache) на работу с SSL-сертификатом. Сервисы вроде Let's Encrypt предоставляют бесплатные сертификаты.
  • На локальной разработке это менее критично, но инструменты вроде Laravel Herd или mkcert позволяют легко настроить локальный HTTPS.

💡 Правило №1 в безопасности API: Нет HTTPS — нет безопасности.


3. Датчики аномалий: Ограничение частоты запросов (Rate Limiting)

Что это? Защита от Brute-force атак (когда злоумышленник пытается подобрать пароль, отправляя тысячи запросов в секунду) и от DoS-атак (когда сервер "заваливают" запросами, чтобы он перестал отвечать). Rate Limiting ограничивает количество запросов, которое один пользователь (или IP-адрес) может сделать за определенный промежуток времени.

Как реализовать?

  • В Laravel: Middleware для ограничения уже встроен! Откройте app/Http/Kernel.php и посмотрите на ключ middlewareGroups['api']. Там уже есть 'throttle:api'. Настройки этого ограничения находятся в app/Providers/RouteServiceProvider.php в методе configureRateLimiting().

    // app/Providers/RouteServiceProvider.php
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });
    }
    
    Это означает: 60 запросов в минуту на одного пользователя (если он авторизован) или на один IP-адрес.

  • В FastAPI: Используется сторонний пакет, например, slowapi.

  • Установка: pip install slowapi

  • Интеграция в main.py:
    # main.py
    from slowapi import Limiter, _rate_limit_exceeded_handler
    from slowapi.util import get_remote_address
    from slowapi.errors import RateLimitExceeded
    
    limiter = Limiter(key_func=get_remote_address)
    app = FastAPI(...)
    
    # Подключаем обработчик ошибок и сам лимитер
    app.state.limiter = limiter
    app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
    
    # Применяем к конкретному эндпоинту
    @router.get("/planets")
    @limiter.limit("5/minute") # 5 запросов в минуту
    def get_planets(request: Request):
        # ...
    

4. Внутренние переборки: Авторизация (не путать с аутентификацией!)

Что это?

  • Аутентификация отвечает на вопрос "Кто ты?".
  • Авторизация отвечает на вопрос "Что тебе разрешено делать?".

Например, обычный пользователь может просматривать планеты, но только пользователь с ролью "администратор" может их удалять.

Как реализовать?

  • В Laravel: Используются Policies (Политики) или Gates (Шлюзы).

  • Создаем политику: php artisan make:policy PlanetPolicy --model=Planet

  • Описываем правила в app/Policies/PlanetPolicy.php:
    class PlanetPolicy
    {
        // Разрешить удаление только пользователям с ролью 'admin'
        public function delete(User $user, Planet $planet): bool
        {
            return $user->role === 'admin';
        }
    }
    
  • Применяем политику в контроллере PlanetController.php:

    public function destroy(Planet $planet)
    {
        // Проверяем, есть ли у текущего пользователя право на удаление
        $this->authorize('delete', $planet);
    
        $planet->delete();
        return response()->json(null, 204);
    }
    

  • В FastAPI: Логика авторизации обычно пишется вручную внутри эндпоинтов, используя информацию о пользователе, полученную из токена.

# (предполагаем, что в токене есть поле 'roles')
def get_current_active_user(token: str = Depends(oauth2_scheme)):
    # ... декодируем токен и получаем пользователя с ролями из БД
    # user = get_user_from_db(username)
    return user # возвращаем объект пользователя

@router.delete("/planets/{planet_id}")
def delete_planet(
    planet_id: int,
    current_user: User = Depends(get_current_active_user)
):
    if "admin" not in current_user.roles:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Недостаточно прав для выполнения этой операции",
        )
    # ... логика удаления ...

5. Проверка грузов и Секретный сейф: Валидация и Переменные окружения

Эти два пункта мы уже реализовали, но важно подчеркнуть их роль в безопасности.

  • Никогда не доверяйте входящим данным (Валидация):

  • Мы использовали $request->validate() в Laravel и Pydantic-модели в FastAPI. Это защищает нас от SQL-инъекций (при использовании Eloquent/SQLAlchemy) и некорректных данных, которые могут сломать приложение. Всегда валидируйте всё, что приходит извне!

  • Храните секреты в .env (Переменные окружения):

  • Ключи от баз данных, секретные ключи для JWT (SECRET_KEY), ключи сторонних сервисов — всё это никогда не должно попадать в систему контроля версий (Git). Для этого и существуют файлы .env, которые добавляются в .gitignore.


Квиз для закрепления

1. Для защиты от перехвата данных в публичных сетях используется:

2. Ограничение частоты запросов (Rate Limiting) в первую очередь защищает от:

3. Вопрос "Что этому пользователю разрешено делать?" решает:

4. Секретные ключи API и пароли от БД следует хранить:


🚀 Завершение курса Поздравляем, командир! Вы успешно завершили все миссии.

Вы прошли путь от новичка, который только слышал об API, до инженера, способного самостоятельно спроектировать, разработать, задокументировать, защитить и протестировать полноценный веб-сервис на двух самых популярных технологиях в своих экосистемах.

Вы освоили универсальный язык REST, научились Laravel и FastAPI и построили для них "Центр Управления Полетами" на чистом JavaScript.

Это огромное достижение. Мир разработки API теперь открыт для вас. Продолжайте исследовать, учиться и строить удивительные вещи.

Конец связи. 🚀

☄ Поддержите миссию

Создание этого учебника — долгий и сложный полёт, который требует немало времени и энергии. Если материал оказался для вас полезным, вы можете помочь пополнить топливные баки нашей экспедиции. Каждая поддержка — это ещё один виток орбиты к новым полезным материалам.

Buy Me a Coffee at ko-fi.com