diff --git a/main_dc/yalarba/api_yal/internal/router/router.go b/main_dc/yalarba/api_yal/internal/router/router.go index 78a2432..6c28f43 100644 --- a/main_dc/yalarba/api_yal/internal/router/router.go +++ b/main_dc/yalarba/api_yal/internal/router/router.go @@ -17,33 +17,27 @@ import ( ) // SetupRouter инициализирует и настраивает основной маршрутизатор приложения -// Параметры: -// - db: подключение к базе данных GORM -// - config: конфигурация приложения -// -// Возвращает: -// - http.Handler: настроенный маршрутизатор с применёнными middleware и маршрутами func SetupRouter(db *gorm.DB, config *config.Config) http.Handler { - // Получаем экземпляр логгера для записи событий zapLogger := logger.Get() zapLogger.Info("Начало настройки маршрутов") - // Создаём новый экземпляр маршрутизатора chi r := chi.NewRouter() - // Добавляем все production middleware для обработки входящих запросов + // ВСЕ middleware должны быть определены ДО маршрутов + // 1. Сначала добавляем production middleware addProductionMiddleware(r, config) - zapLogger.Debug("Production middleware успешно добавлены") + + // 2. Затем добавляем middleware аутентификации (он тоже применяется ко всем маршрутам) + r.Use(CastomMiddleware.AuthMiddlewareWithContext) + zapLogger.Debug("Auth middleware применён") - // Эндпоинт для проверки работоспособности сервиса (health check) - // Используется мониторингом и системами оркестрации для проверки статуса приложения + // 3. И только потом регистрируем маршруты + // Health check (не требует аутентификации, поэтому должен быть выше AuthMiddleware) r.Get("/health", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - - // Формируем и отправляем JSON-ответ со статусом healthy + if err := json.NewEncoder(w).Encode(map[string]string{"status": "healthy"}); err != nil { - // Логируем ошибку при невозможности отправить ответ zapLogger.Error("Ошибка при отправке health check ответа", zap.String("path", r.URL.Path), zap.Error(err), @@ -52,123 +46,60 @@ func SetupRouter(db *gorm.DB, config *config.Config) http.Handler { }) zapLogger.Debug("Health check маршрут зарегистрирован") - // Добавляем middleware для аутентификации ко всем последующим маршрутам - // Все маршруты после этого middleware будут требовать валидный контекст аутентификации - r.Use(CastomMiddleware.AuthMiddlewareWithContext) - zapLogger.Debug("Auth middleware применён ко всем маршрутам") + // Здесь можно добавить другие маршруты, которые будут защищены аутентификацией + // r.Mount("/api/v1", apiRoutes(db, config)) - // TODO: Здесь можно добавить регистрацию дополнительных маршрутов - // Например: r.Mount("/api/v1", apiRoutes(db, config)) + zapLogger.Info("Настройка маршрутов завершена") - zapLogger.Info("Настройка маршрутов завершена успешно") - - // Логируем все зарегистрированные маршруты для отладки и мониторинга + // Логируем маршруты (опционально) routeLogger := logger.NewRouteLogger(logger.NewWrapper(zapLogger)) routeLogger.LogRoutes(r) - zapLogger.Debug("Все маршруты залогированы") return r } -// addProductionMiddleware добавляет все необходимые middleware для production окружения -// Функция применяет стандартный набор middleware для обработки запросов: -// - Идентификация запросов -// - Логирование -// - Безопасность -// - Сжатие ответов -// - CORS настройки -// -// Параметры: -// - r: экземпляр маршрутизатора chi -// - config: конфигурация приложения для настройки middleware под окружение +// addProductionMiddleware добавляет все middleware для production func addProductionMiddleware(r *chi.Mux, config *config.Config) { - // Request ID middleware - добавляет уникальный ID к каждому запросу - // Позволяет отслеживать запрос на протяжении всего жизненного цикла + // Базовые middleware r.Use(ChiMiddleware.RequestID) - - // Real IP middleware - корректно определяет реальный IP клиента (за прокси) - // Важно для правильного логирования и rate limiting'а r.Use(ChiMiddleware.RealIP) - - // Logger middleware - логирует все запросы в формате Apache - // Предоставляет базовую информацию о входящих запросах r.Use(ChiMiddleware.Logger) - - // Recoverer middleware - восстанавливает после паники и возвращает 500 - // Предотвращает падение всего приложения из-за паники в обработчиках r.Use(ChiMiddleware.Recoverer) - - // Timeout middleware - устанавливает таймаут на запросы (30 секунд) - // Защищает от "висящих" запросов, которые могут занять слишком много времени r.Use(ChiMiddleware.Timeout(30 * time.Second)) - - // Compress middleware - сжимает ответы (gzip) - // Уменьшает размер передаваемых данных, улучшает производительность - // Уровень сжатия 5 (среднее между скоростью и степенью сжатия) r.Use(ChiMiddleware.Compress(5, "gzip")) - - // StripSlashes middleware - удаляет слеши в конце URL или редиректит - // Нормализует URL'ы для единообразия маршрутизации r.Use(ChiMiddleware.StripSlashes) - - // CORS middleware - настройка CORS для production - // Позволяет контролировать доступ к API из браузерных приложений + + // CORS r.Use(cors.Handler(cors.Options{ - // Разрешённые источники (origins) из конфигурации - AllowedOrigins: config.CORS.AllowedOrigins, - // Разрешённые HTTP методы - AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"}, - // Разрешённые заголовки запросов - AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Request-ID"}, - // Заголовки, доступные клиенту при чтении ответа - ExposedHeaders: []string{"Link", "X-Request-ID"}, - // Разрешить передачу cookies и HTTP-аутентификацию + AllowedOrigins: config.CORS.AllowedOrigins, + AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"}, + AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Request-ID"}, + ExposedHeaders: []string{"Link", "X-Request-ID"}, AllowCredentials: true, - // Время кэширования preflight запросов (в секундах) - MaxAge: 300, + MaxAge: 300, })) - - // Content-Type middleware - проверяет Content-Type для POST/PUT запросов - // Гарантирует, что клиенты отправляют данные в ожидаемом формате + + // Content-Type проверка r.Use(ChiMiddleware.AllowContentType("application/json", "application/xml")) - - // Дополнительные middleware в зависимости от конфигурации - if config.Environment == "development" { - // Добавляем дополнительное логирование для разработки - // В dev-режиме полезно иметь более подробную информацию о запросах - r.Use(ChiMiddleware.Logger) - } - + + // Rate limiting if config.RateLimit.Enabled { - // Добавляем rate limiting если включено в конфиге - // Защищает от DDoS атак и чрезмерного использования ресурсов r.Use(ChiMiddleware.Throttle(config.RateLimit.RequestsPerSecond)) } - - // Security headers middleware - добавляет заголовки безопасности к каждому ответу - // Защищает от распространённых веб-уязвимостей + + // Security headers r.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Защита от MIME-снiffing атак w.Header().Set("X-Content-Type-Options", "nosniff") - - // Защита от clickjacking атак w.Header().Set("X-Frame-Options", "DENY") - - // Включает защиту от XSS в браузерах w.Header().Set("X-XSS-Protection", "1; mode=block") - - // Контролирует, сколько информации о реферере передаётся при переходах w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin") - - // Для production окружения включаем HSTS (HTTP Strict Transport Security) - // Заставляет браузер использовать только HTTPS соединения + if config.Environment == "production" { w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") } - - // Передаём управление следующему middleware или обработчику + next.ServeHTTP(w, r) }) }) -} +} \ No newline at end of file