package middleware import ( "context" "log" "net/http" "strings" "tailly_back_v2/pkg/auth" ) const ( authorizationHeader = "Authorization" bearerPrefix = "Bearer " userIDKey = "userID" ) // AuthMiddleware проверяет JWT токен и добавляет userID в контекст func AuthMiddleware(tokenAuth *auth.TokenAuth) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Printf("Middleware: путь %s", r.URL.Path) // Пропускаем WebSocket маршрут if r.URL.Path == "/ws" { log.Printf("Middleware: пропускаем /ws") next.ServeHTTP(w, r) return } if strings.Contains(r.Header.Get("Upgrade"), "websocket") { next.ServeHTTP(w, r) return } if r.Method == http.MethodOptions { next.ServeHTTP(w, r) return } // Извлекаем заголовок Authorization header := r.Header.Get(authorizationHeader) if header == "" { next.ServeHTTP(w, r) return } // Проверяем формат заголовка if !strings.HasPrefix(header, bearerPrefix) { next.ServeHTTP(w, r) return } // Извлекаем токен token := strings.TrimPrefix(header, bearerPrefix) if token == "" { next.ServeHTTP(w, r) return } // Валидируем токен userID, err := tokenAuth.ValidateAccessToken(token) if err != nil { next.ServeHTTP(w, r) return } // Добавляем userID в контекст ctx := context.WithValue(r.Context(), userIDKey, userID) next.ServeHTTP(w, r.WithContext(ctx)) }) } } func WebSocketMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Upgrade") == "websocket" { // Используем оригинальный ResponseWriter для WebSocket next.ServeHTTP(w, r) return } // Для обычных HTTP запросов используем наш кастомный writer rw := &responseWriter{ResponseWriter: w, status: http.StatusOK} next.ServeHTTP(rw, r) }) }