// middleware/auth.go package middleware import ( "context" "net/http" "strings" "api_bb/internal/models" "api_bb/internal/repository" "api_bb/internal/service" ) type contextKey string const ( UserIDKey contextKey = "userID" UserKey contextKey = "user" ) func AuthMiddleware(jwtService service.JWTService, userRepo repository.UserRepository) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var tokenString string // Пробуем получить токен из заголовка Authorization authHeader := r.Header.Get("Authorization") if strings.HasPrefix(authHeader, "Bearer ") { tokenString = strings.TrimPrefix(authHeader, "Bearer ") } // Если нет в заголовке, пробуем из куки if tokenString == "" { cookie, err := r.Cookie("auth_token") if err == nil { tokenString = cookie.Value } } if tokenString == "" { next.ServeHTTP(w, r) return } token, err := jwtService.ValidateToken(tokenString) if err != nil || !token.Valid { next.ServeHTTP(w, r) return } userID, err := jwtService.ExtractUserID(token) if err != nil { next.ServeHTTP(w, r) return } user, err := userRepo.FindByID(userID) if err != nil { next.ServeHTTP(w, r) return } // Добавляем пользователя в контекст ctx := context.WithValue(r.Context(), UserIDKey, userID) ctx = context.WithValue(ctx, UserKey, user) next.ServeHTTP(w, r.WithContext(ctx)) }) } } // RequireAuth middleware требует аутентификации func RequireAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { userID := r.Context().Value(UserIDKey) if userID == nil { http.Error(w, `{"error": "Authentication required"}`, http.StatusUnauthorized) return } next.ServeHTTP(w, r) }) } // GetUserFromContext получает пользователя из контекста func GetUserFromContext(ctx context.Context) (*models.User, bool) { user, ok := ctx.Value(UserKey).(*models.User) return user, ok }