У цій лекції ми реалізуємо публічний 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! 🚀
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ