520bd7243d6f1aff4bd1b48a5d17d9e976899ffa
The frontend proxy fix alone was incomplete. Backend slowapi used the default
get_remote_address (request.client.host), which is the proxy's IP because
uvicorn runs without --proxy-headers — so the relayed x-forwarded-for was
ignored and all users still shared one rate-limit bucket.
- Add app/ratelimit.py: shared `limiter` + `client_ip_key` that reads
x-forwarded-for[0] → x-real-ip → peer. Replaces the three independent
Limiter(get_remote_address) instances in main.py / posts.py / prices.py
(which also had separate, non-shared storage).
- Register SlowAPIMiddleware so default_limits ("60/minute") applies to EVERY
route. Previously only the 2 decorated read endpoints were limited; all
signed-mutation routes had no rate limit at all (the "20/min per-route"
comment was aspirational — no such decorator existed).
- Add tests/test_ratelimit.py (7 tests): XFF precedence, fallbacks, two users
behind one proxy get distinct keys, middleware-registered guard.
72 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 填 backend .env(生产值):
POSTGRES_PASSWORD=强密码 FRONTEND_URL=https://你的前端域名 ENCRYPTION_KEY=之前生成的那个 AI_API_KEY=sk-... ENVIRONMENT=production 2. 改前端 .env.local:
NEXT_PUBLIC_API_URL=https://api.你的域名.com NEXT_PUBLIC_WS_URL=wss://api.你的域名.com 启动:
cd backend docker compose up -d
Description
Languages
Python
99.6%
Shell
0.3%
Dockerfile
0.1%