v0.1.34: кэш валидации JWT (TTL 5 мин + grace 2 мин) — консоль устойчива к флаку шлюза

This commit is contained in:
“Naeel”
2026-08-14 14:09:49 +04:00
parent 0d5dbaba4f
commit 0f24658fc7
5 changed files with 129 additions and 6 deletions
+8 -3
View File
@@ -65,6 +65,7 @@ type Handler struct {
func NewHandler(store *tenant.TenantStore, adminToken string) *Handler {
nubesEndpoint := os.Getenv("NUBES_ENDPOINT")
// Если не задан — пустой: PingNubesAPI переберёт все стенды сам.
auth.StartTokenCacheCleanup() // фоновая очистка кэша валидации (идемпотентно)
return &Handler{store: store, adminToken: adminToken, nubesEndpoint: nubesEndpoint}
}
@@ -238,6 +239,9 @@ func (h *Handler) jwtAuth(w http.ResponseWriter, r *http.Request) {
jsonErr(w, http.StatusForbidden, "token rejected by cloud API: "+err.Error())
return
}
// Логин — всегда свежая проверка; после успеха прогреваем кэш,
// чтобы дальнейшие запросы консоли не дёргали нестабильный шлюз.
auth.WarmTokenCache(req.Token)
// Auto-provisioning: тенант и ключи детерминированы из email.
// Токен — только аутентификация; ключи в ответ не возвращаем (GET /ui/api/credentials).
@@ -320,11 +324,12 @@ func (h *Handler) jwtMiddleware(next http.Handler) http.Handler {
return
}
// Повторно валидируем токен в nubes API на каждый UI API запрос,
// чтобы отозванные токены не оставались валидными до повторного логина.
// Повторная валидация через кэш: в течение TTL шлюз не вызывается
// (шлюз нестабилен с IP платформы), отозванный токен умрёт через TTL,
// явный 401/403 от шлюза сбрасывает кэш.
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
if err := auth.PingNubesAPI(ctx, h.nubesEndpoint, token); err != nil {
if err := auth.PingNubesAPICached(ctx, h.nubesEndpoint, token); err != nil {
jsonErr(w, http.StatusForbidden, "token rejected by cloud API: "+err.Error())
return
}