feat(api): лимиты частоты запросов (AGENT.md 8.6)

- httpx.RateLimiter: token bucket в памяти с уборкой неактивных ключей и
  подменяемым источником времени;
- login/register — 5 запросов в минуту на IP, весь API — 120 в минуту на
  пользователя (по хэшу токена сессии) или на IP для анонимных запросов;
- превышение отдаёт 429 с Retry-After и retry_after_ms в конверте ошибки;
- тесты: наполнение и пополнение ведра, независимость ключей, 429 на ручке
  входа.
This commit is contained in:
2026-09-19 21:51:47 +03:00
parent 6d7062dc2f
commit c059cd9f51
5 changed files with 247 additions and 7 deletions
+6 -2
View File
@@ -48,8 +48,12 @@ func (s *Server) clearSessionCookie() *http.Cookie {
// registerAuthRoutes вешает ручки аутентификации на chi: cookie и заголовки
// выставляются напрямую, а контракт описан в OpenAPI (docs.go).
func (s *Server) registerAuthRoutes(router chi.Router) {
router.Post("/auth/register", s.handleRegister)
router.Post("/auth/login", s.handleLogin)
// Вход и регистрация дополнительно ограничены по IP (AGENT.md 8.6).
authLimit := s.authLimiter.Middleware(func(r *http.Request) string {
return httpx.ClientIP(r, nil)
})
router.With(authLimit).Post("/auth/register", s.handleRegister)
router.With(authLimit).Post("/auth/login", s.handleLogin)
router.Post("/auth/logout", s.handleLogout)
router.Post("/auth/logout-all", s.handleLogoutAll)
router.Get("/auth/sessions", s.handleListSessions)