JavaRush /Курсы /Модуль 4: FastAPI /Пример защиты API и CORS для публичного приложения

Пример защиты API и CORS для публичного приложения

Модуль 4: FastAPI
21 уровень , 9 лекция
Открыта

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

Требования к публичному API

Ваше API готовы использовать миллионы пользователей? Если мы говорим о публичном доступе, нужно подумать о нескольких ключевых аспектах:

  • Доступность: API должно быть доступным для фронтенда, но не для злоумышленников.
  • Защита данных: передача данных должна быть зашифрована.
  • Контроль доступа: доступ к данным или сервисам API должен быть ограничен в зависимости от авторизации.
  • Управление CORS: ваш API должен работать с определенными клиентами (например, React или Angular), но не быть открытым для всех.

Теперь, когда вы понимаете общую задачу, давайте погрузимся в реализацию.


Базовая настройка CORS и защита

Для начала настроим CORS и разрешим доступ только конкретному фронтенд-клиенту. Представьте, что у нас есть React-приложение, размещенное на домене https://myfrontend.com.

Шаг 1: Установка fastapi.middleware.cors

FastAPI делает настройку CORS простой благодаря встроенной поддержке. Если вы еще не устанавливали эту библиотеку, выполняем:


pip install fastapi[all]

Теперь готовимся к магии.

Шаг 2: Настройка CORS в FastAPI

Добавим в проект middleware для обработки CORS-запросов. Это позволит нам указать, какие источники запросов разрешены, какие методы можно использовать, а также какие дополнительные заголовки поддерживаются.


from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# Настраиваем разрешенные источники
origins = [
    "https://myfrontend.com",  # Включаем ваш фронтенд-домен
]

# Добавляем CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],  # Разрешить конкретные методы
    allow_headers=["*"],  # Разрешить все заголовки
)

Вот и всё! Теперь ваш API готов работать только с запросами, исходящими с домена https://myfrontend.com. Любой другой источник будет отвергнут.


3. Защита эндпоинтов с помощью токенов

API без защиты — как дом без дверей: любой может войти. Поэтому мы добавим JWT-токены для управления доступом. Если вы не уверены, что такое JWT, подгляните в лекцию 33.

Шаг 1: Установка библиотек

Для работы с JWT нам понадобится библиотека pyjwt. Установите её:


pip install pyjwt

Шаг 2: Генерация токенов

Напишем небольшой пример, где пользователь получает токен после ввода логина и пароля. Используем для этого библиотеку jwt.


import jwt
from datetime import datetime, timedelta

SECRET_KEY = "mysecretkey"  # Замените на собственный ключ

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=30)  # Токен действует 30 минут
    to_encode.update({"exp": expire})
    token = jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")
    return token

# Создаем токен для пользователя
token = create_access_token({"sub": "user_id"})
print("Ваш токен:", token)

Шаг 3: Проверка токенов

Теперь добавим защиту эндпоинтов, проверяя токены из заголовка запроса.


from fastapi import Depends, HTTPException, Header
from jose import jwt, JWTError

async def verify_token(authorization: str = Header(None)):
    try:
        payload = jwt.decode(authorization, SECRET_KEY, algorithms=["HS256"])
        return payload  # Возвращаем полезную информацию из токена
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

@app.get("/secure-data")
async def get_secure_data(payload: dict = Depends(verify_token)):
    return {"message": "Welcome!", "user": payload["sub"]}

Теперь эндпоинт /secure-data доступен только тем, у кого есть корректный токен.


4. Настройка SSL (HTTPS)

Веб-приложение без HTTPS? Это как посылка с мороженым без холодильника: всё растает по дороге. Чтобы данные не были перехвачены злоумышленниками, настраиваем SSL.

Шаг 1: Создание самоподписанного сертификата

Для тестирования можно создать сертификат с помощью OpenSSL:


openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

Теперь у нас есть два файла: key.pem (приватный ключ) и cert.pem (сертификат).

Шаг 2: Настройка SSL в Uvicorn

Обновим команду запуска приложения:


uvicorn main:app --host 0.0.0.0 --port 443 --ssl-keyfile=key.pem --ssl-certfile=cert.pem

Ваше API теперь доступно по HTTPS. Сертификат самоподписанный, но для реальных проектов используйте сертификаты от авторитетных центров, таких как Let's Encrypt.


Полный пример защиты публичного API

Объединим всё: CORS, JWT-токены и SSL. Вот как будет выглядеть итоговый код:


from fastapi import FastAPI, Depends, HTTPException, Header
from fastapi.middleware.cors import CORSMiddleware
from jose import jwt, JWTError
from datetime import datetime, timedelta

app = FastAPI()

SECRET_KEY = "mysecretkey"

# Настраиваем CORS
origins = ["https://myfrontend.com"]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["GET", "POST"],
    allow_headers=["*"],
)

# Генерация и проверка токенов
def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=30)
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")

async def verify_token(authorization: str = Header(None)):
    try:
        payload = jwt.decode(authorization, SECRET_KEY, algorithms=["HS256"])
        return payload
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

@app.post("/login")
async def login():
    token = create_access_token({"sub": "user_id"})
    return {"access_token": token}

@app.get("/secure-data")
async def secure_data(payload: dict = Depends(verify_token)):
    return {"message": "Welcome back!", "user": payload["sub"]}

Этот код объединяет все аспекты безопасности. Добавьте SSL, чтобы завершить настройку, и ваш API готов к работе.


Теперь ваш API может безопасно взаимодействовать с фронтендом, обрабатывая кросс-доменные запросы, защищая данные через JWT и обеспечивая безопасность передачи данных с помощью SSL. Все клиенты, кроме тех, кому вы явно позволили доступ, останутся за бортом. Растите здоровый и надёжный API! 🚀

1
Задача
Модуль 4: FastAPI, 21 уровень, 9 лекция
Недоступна
Защищённый GET-запрос с использованием JWT
Защищённый GET-запрос с использованием JWT
1
Задача
Модуль 4: FastAPI, 21 уровень, 9 лекция
Недоступна
Комбинированная защита API (CORS, JWT, и HTTPS)
Комбинированная защита API (CORS, JWT, и HTTPS)
3
Опрос
Обработка ошибок CORS и диагностика, 21 уровень, 9 лекция
Недоступен
Обработка ошибок CORS и диагностика
Обработка ошибок CORS и диагностика
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Олег Е Уровень 90
29 ноября 2025
Отлично! Спасибо за курс!