JavaRush /Курси /Модуль 4: FastAPI /Приклад захисту API і CORS для публічного застосунку

Приклад захисту API і CORS для публічного застосунку

Модуль 4: FastAPI
Рівень 21 , Лекція 9
Відкрита

У цій лекції ми реалізуємо публічний API, забезпечивши його захист від несанкціонованого доступу і налаштувавши CORS для безпечної роботи з frontend-застосунком. Ми також обговоримо, як забезпечити захист через SSL і працювати з безпекою в реальному житті.

Вимоги до публічного API

Твій API готовий використовувати мільйони користувачів? Якщо йдеться про публічний доступ, треба подумати про кілька ключових аспектів:

  • Доступність: API має бути доступним для frontend, але не для зловмисників.
  • Захист даних: передача даних має бути зашифрована.
  • Контроль доступу: доступ до даних або сервісів API має бути обмежений залежно від авторизації.
  • Керування CORS: твій API має працювати з певними клієнтами (наприклад, React або Angular), але не бути відкритим для всіх.

Тепер, коли ти розумієш загальну задачу, давай зануримось в реалізацію.


Базове налаштування CORS і захист

Для початку налаштуємо CORS і дозволимо доступ тільки конкретному frontend-клієнту. Уяви, що в нас є 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",  # Підключаємо домен твого frontend
]

# Додаємо 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 може безпечно взаємодіяти з frontend, обробляючи крос-доменні запити, захищаючи дані через JWT і забезпечуючи безпеку передачі даних за допомогою SSL. Усі клієнти, окрім тих, кому ти явно дозволив доступ, залишаться за бортом. Розвивай здоровий і надійний API! 🚀

3
Опитування
Обробка помилок CORS та діагностика, рівень 21, лекція 9
Недоступний
Обробка помилок CORS та діагностика
Обробка помилок CORS та діагностика
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ