π‘οΈ ΠΠ°ΠΊ Π·Π°ΠΊΠ°Π»ΠΈΡΡ FastAPI ΠΎΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠ΅ΠΉ (ΠΈ Π½Π΅ Π΄Π°ΡΡ Ρ Π°ΠΊΠ΅ΡΠ°ΠΌ ΠΈΡΠΏΠΎΡΡΠΈΡΡ ΠΆΠΈΠ·Π½Ρ Π²Π°ΡΠ΅ΠΌΡ ΠΊΠΎΡΠΈΠΊΡ)
FastAPI β ΠΊΠ°ΠΊ ΠΏΡΡΠΈΡΡΡΠΉ ΠΊΠΎΡ: Π»ΡΠ³ΠΊΠΈΠΉ, Π±ΡΡΡΡΡΠΉ, ΠΎΡΠ·ΡΠ²ΡΠΈΠ²ΡΠΉ ΠΈ Π²ΠΎΠΎΠ±ΡΠ΅ ΡΡΠ΄ΠΎ-ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ. ΠΠΎ, ΠΊΠ°ΠΊ ΠΈ ΠΊΠΎΡ, ΠΎΠ½ ΡΡΠ΅Π±ΡΠ΅Ρ ΡΡ ΠΎΠ΄Π° ΠΈ Π·Π°ΡΠΈΡΡ. ΠΠ°ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅ ΡΠ»Π΅Π³Π°Π½ΡΠ½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°ΡΡ Π»Π°ΠΊΠΎΠΌΡΠΌ ΠΊΡΡΠΎΡΠΊΠΎΠΌ Π΄Π»Ρ Π°ΡΠ°ΠΊ, Π΅ΡΠ»ΠΈ Π΅Π³ΠΎ Π½Π΅ ΡΠΊΡΠ΅ΠΏΠΈΡΡ.
Π‘Π΅Π³ΠΎΠ΄Π½Ρ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠΌ, ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°ΡΡ Π²Π°ΡΠ΅ FastAPI-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ ΡΡΡΠΎΠΉΡΠΈΠ²ΡΠΌ ΠΊ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡΠΌ β Π±Π΅Π· ΡΠ°Π½Π°ΡΠΈΠ·ΠΌΠ°, Π½ΠΎ Ρ Π»ΡΠ±ΠΎΠ²ΡΡ ΠΊ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ β€οΈ.
π§© 1. ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΈ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ: ΠΌΠ΅Π½ΡΡΠ΅ ΡΡΠ°ΡΡΡ β ΠΌΠ΅Π½ΡΡΠ΅ Π΄ΡΡ
Π‘Π°ΠΌΠ°Ρ ΡΠ°ΡΡΠ°Ρ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡ β ΡΡΡΠ°ΡΠ΅Π²ΡΠΈΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ.
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π²ΡΠΎΠ΄Π΅:
pip install safety safety check
ΠΈΠ»ΠΈ Π² CI/CD β pip-audit, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΎΠ²Π΅ΡΠΈΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Π½Π° ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ.
Π Π΅ΡΡ Π»ΡΡΡΠ΅ β ΡΠΈΠΊΡΠΈΡΡΠΉΡΠ΅ Π²Π΅ΡΡΠΈΠΈ Π² requirements.txt ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠΉΡΠ΅ ΠΈΡ
ΡΠ°Π· Π² ΠΌΠ΅ΡΡΡ (ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡΠ°Π²ΠΈΡΡ cron-Π·Π°Π΄Π°ΡΡ ΠΈΠ»ΠΈ GitLab pipeline).
π‘ ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΠΉ ΡΠ°ΠΊΡ: Π² 2023 Π³ΠΎΠ΄Ρ Π±ΠΎΠ»Π΅Π΅ 60% Python-ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠ΅ΠΉ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΠ»ΠΈΡΡ ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π° ΡΡΠΎΡΠΎΠ½Π½ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ. ΠΠΎΡΠΈΠΊ-Π΄Π΅Π²ΠΎΠΏΡ Π±Ρ Π·Π°ΠΏΠ»Π°ΠΊΠ°Π», Π΅ΡΠ»ΠΈ Π±Ρ ΡΠ²ΠΈΠ΄Π΅Π» Π½Π΅Π·Π°ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ.
π 2. ΠΠ°ΡΡΡΠΎΠΉΡΠ΅ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ
FastAPI Π»Π΅Π³ΠΊΠΎ ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΡΠ΅ΡΡΡ Ρ Starlette Middleware.
ΠΠΎΠ±Π°Π²ΡΡΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄Π΅Π»Π°ΡΡ ΠΆΠΈΠ·Π½Ρ Π·Π»ΠΎΡΠΌΡΡΠ»Π΅Π½Π½ΠΈΠΊΠΎΠ² ΡΠ»ΠΎΠΆΠ½Π΅Π΅:
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
from starlette.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
app.add_middleware(
TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]
)
app.add_middleware(
CORSMiddleware,
allow_origins=["https://example.com"],
allow_credentials=True,
allow_methods=["GET", "POST"],
allow_headers=["*"],
)
Π’Π°ΠΊΠΆΠ΅ ΡΡΠΎΠΈΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ HTTP Security Headers ΡΠ΅ΡΠ΅Π· reverse proxy (Nginx, Traefik):
add_header X-Frame-Options "DENY"; add_header X-Content-Type-Options "nosniff"; add_header Referrer-Policy "strict-origin"; add_header Content-Security-Policy "default-src 'self'";
π§βπ» 3. ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ Π²Ρ ΠΎΠ΄Π½ΡΡ Π΄Π°Π½Π½ΡΡ
FastAPI β ΡΠ΅ΠΌΠΏΠΈΠΎΠ½ ΠΏΠΎ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΡ Pydantic, Π½ΠΎ Π½Π΅ Π·Π°Π±ΡΠ²Π°ΠΉΡΠ΅ ΠΏΡΠΎ:
- ΡΡΡΠΎΠ³ΠΈΠ΅ ΡΠΈΠΏΡ (
constr,conint,EmailStr), - ΡΠ΅Π³ΡΠ»ΡΡΠΊΠΈ (
regex=), - ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΡ (
@validator).
from pydantic import BaseModel, EmailStr, constr
class User(BaseModel):
username: constr(min_length=3, max_length=32, regex=r"^[a-zA-Z0-9_]+quot;)
email: EmailStr
Π’Π°ΠΊ Π²Ρ Π·Π°ΡΠΈΡΠΈΡΠ΅ΡΡ ΠΎΡ SQL-ΠΈΠ½ΡΠ΅ΠΊΡΠΈΠΉ, XSS ΠΈ ΠΏΡΠΎΡΠ΅ΠΉ Π³Π°Π΄ΠΎΡΡΠΈ Π΅ΡΡ Π½Π° ΡΡΠΎΠ²Π½Π΅ Π΄Π°Π½Π½ΡΡ .
πΈ ΠΠΎΡΠ°ΡΠΈΠΉ Π»Π°ΠΉΡΡ Π°ΠΊ: Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΡ β ΠΊΠ°ΠΊ ΡΠΈΡΡΠΊΠ° ΡΠ΅ΡΡΡΠΈ. ΠΠ΅Π»Π°ΠΉΡΠ΅ Π΅Ρ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎ, ΠΈ Π±ΡΠ΄Π΅Ρ ΠΌΠ΅Π½ΡΡΠ΅ Π½Π΅ΠΏΡΠΈΡΡΠ½ΡΡ ΡΡΡΠΏΡΠΈΠ·ΠΎΠ².
π§± 4. ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ² (Rate Limiting)
ΠΠ΅Π· Π»ΠΈΠΌΠΈΡΠΎΠ² Π²Π°Ρ ΡΠ΅ΡΠ²Π΅Ρ ΠΌΠΎΠΆΠ΅Ρ Π»Π΅Π³ΠΊΠΎ Β«ΡΠ»Π΅ΡΠ΅ΡΡ Π² ΠΊΠΎΡΠΌΠΎΡΒ» ΠΎΡ DDoS ΠΈΠ»ΠΈ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎΠ³ΠΎ ΡΠΊΡΠΈΠΏΡΠ°. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ middleware, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ slowapi
from slowapi import Limiter from slowapi.util import get_remote_address from fastapi import FastAPI limiter = Limiter(key_func=get_remote_address) app = FastAPI() app.state.limiter = limiter
Π’Π΅ΠΏΠ΅ΡΡ Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΠΊΡΠΎ-ΡΠΎ Π·Π°Ρ ΠΎΡΠ΅Ρ Π·Π°ΡΠΏΠ°ΠΌΠΈΡΡ Π²Π°Ρ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ, ΠΎΠ½ ΡΠΏΡΡΡΡΡ Π² ΠΌΡΠ³ΠΊΠΈΠΉ, Π½ΠΎ Π½Π°Π΄ΡΠΆΠ½ΡΠΉ firewall.
π§° 5. Π₯ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΠ΅ΡΠΎΠ² ΠΈ ΡΠΎΠΊΠ΅Π½ΠΎΠ²
ΠΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Ρ
ΡΠ°Π½ΠΈΡΠ΅ ΠΏΠ°ΡΠΎΠ»ΠΈ ΠΈ API-ΠΊΠ»ΡΡΠΈ Π² .env ΡΡΠ΄ΠΎΠΌ Ρ ΠΊΠΎΠ΄ΠΎΠΌ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ.
ΠΡΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Vault, Doppler, AWS Secrets Manager ΠΈΠ»ΠΈ Ρ
ΠΎΡΡ Π±Ρ Kubernetes secrets.
Π Π΅ΡΠ»ΠΈ Π²ΡΡ-ΡΠ°ΠΊΠΈ .env, ΡΠΎ:
- Π΄ΠΎΠ±Π°Π²ΡΡΠ΅
.envΠ².gitignore; - ΡΠΈΡΡΡΠΉΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ
fernetΠΈΠ»ΠΈdotenv-vault.
πΎ Π€Π°ΠΊΡ: Π² 2024 Π³ΠΎΠ΄Ρ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΠΈ GitGuardian Π½Π°ΡΠ»ΠΈ 10 ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ΠΎΠ² ΡΡΠ΅ΠΊΡΠΈΡ ΡΠΎΠΊΠ΅Π½ΠΎΠ² Π² ΠΏΡΠ±Π»ΠΈΡΠ½ΡΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡΡ GitHub. ΠΠ°ΠΆΠ΄ΡΠΉ Π²ΡΠΎΡΠΎΠΉ ΠΊΠΎΡ-ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΡΠΊΠ°Π·Π°Π» ΡΠΎΠ³Π΄Π°: Β«ΠΌΡΡ...Β»
π§ 6. HTTPS ΠΈ HSTS
ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ HTTPS.
Π Nginx ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ:
listen 443 ssl; ssl_certificate /etc/ssl/certs/fullchain.pem; ssl_certificate_key /etc/ssl/private/privkey.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
𧨠7. ΠΠ·ΠΎΠ»ΡΡΠΈΡ ΠΈ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠ° ΠΏΡΠ°Π²
ΠΡΠ»ΠΈ Π²Ρ Π΄Π΅ΠΏΠ»ΠΎΠΈΡΠ΅ FastAPI Π² Docker:
- ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Π½Π΅ root ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ;
- Π²ΠΊΠ»ΡΡΠ°ΠΉΡΠ΅
read-onlyΡΠ°ΠΉΠ»ΠΎΠ²ΡΡ ΡΠΈΡΡΠ΅ΠΌΡ, Π΅ΡΠ»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ; - ΠΎΠ³ΡΠ°Π½ΠΈΡΡΡΠ΅ Π΄ΠΎΡΡΡΠΏ ΠΏΠΎ ΡΠ΅ΡΠΈ;
- ΠΈ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅
seccomp,no-new-privileges.
FROM python:3.12-slim WORKDIR /app COPY . . RUN useradd -m appuser USER appuser CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
πΎ ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
FastAPI β ΡΡΠΎ ΠΌΠΎΡΠ½ΡΠΉ, Π½ΠΎ ΡΡΠ΅Π±ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΡΠΉ Π·Π²Π΅ΡΡΠΊ.
ΠΡΠ»ΠΈ ΡΠ΄Π΅Π»ΠΈΡΡ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ β ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡΠΌ, ΡΠΎΠΊΠ΅Π½Π°ΠΌ, ΡΠΈΠΏΠ°ΠΌ, ΠΈΠ·ΠΎΠ»ΡΡΠΈΠΈ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΠΌ β Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΠ°Π½Π΅Ρ ΠΊΡΠ΅ΠΏΡΠ΅, ΡΠ΅ΠΌ ΠΊΠΎΠ³ΡΠΈ ΠΊΠΎΡΠ° Π½Π° Π·Π°Π½Π°Π²Π΅ΡΠΊΠ΅ πββ¬.
ΠΠ΅ Π·Π°Π±ΡΠ²Π°ΠΉΡΠ΅: ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ Π½Π΅ ΡΠΏΡΡ. Π Π·Π½Π°ΡΠΈΡ, ΠΏΡΡΡΡ Π²Π°Ρ CI/CD ΠΊΠ°ΠΆΠ΄ΡΠΉ Π΄Π΅Π½Ρ Π±ΡΠ΄Π΅Ρ ΠΊΠ°ΠΊ Π΄Π΅ΠΆΡΡΠ½ΡΠΉ ΠΊΠΎΡ, ΠΏΠ°ΡΡΡΠ»ΠΈΡΡΡΡΠΈΠΉ ΡΠ΅ΡΠ²Π΅ΡΠ½ΡΡ ΠΊΠΎΠΌΠ½Π°ΡΡ.