Files
tp/main_dc/BB/api_bb/pkg/middleware/auth.go
T
valitovgaziz 15357fd3c0 create and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarba
2025-10-24 05:22:44 +05:00

138 lines
3.7 KiB
Go

// middleware/auth.go
package middleware
import (
"context"
"net/http"
"strings"
"api_bb/internal/models"
"api_bb/internal/repository"
"api_bb/internal/service"
"api_bb/pkg/logger"
"go.uber.org/zap"
)
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
logger := logger.Get()
logger.Debug("authMiddleware Start")
// Пробуем получить токен из заголовка Authorization
authHeader := r.Header.Get("Authorization")
if strings.HasPrefix(authHeader, "Bearer ") {
tokenString = strings.TrimPrefix(authHeader, "Bearer ")
logger.Debug("Token found in Authorization header")
}
// Если нет в заголовке, пробуем из куки
if tokenString == "" {
cookie, err := r.Cookie("auth_token")
if err == nil {
tokenString = cookie.Value
logger.Debug("Token found in auth_token cookie")
} else {
logger.Debug("No auth_token cookie found", zap.Error(err))
}
}
if tokenString == "" {
logger.Debug("No token found in request")
next.ServeHTTP(w, r)
return
}
token, err := jwtService.ValidateToken(tokenString)
if err != nil || !token.Valid {
logger.Warn("Invalid token",
zap.Error(err),
zap.Bool("token_valid", token != nil && token.Valid))
next.ServeHTTP(w, r)
return
}
userID, err := jwtService.ExtractUserID(token)
if err != nil {
logger.Error("Failed to extract user ID from token",
zap.Error(err))
next.ServeHTTP(w, r)
return
}
logger.Debug("Extracted user ID from token",
zap.Any("user_id", userID))
user, err := userRepo.FindByID(userID)
if err != nil {
logger.Error("Failed to find user by ID",
zap.Any("user_id", userID),
zap.Error(err))
next.ServeHTTP(w, r)
return
}
// Добавляем пользователя в контекст
ctx := context.WithValue(r.Context(), UserIDKey, userID)
ctx = context.WithValue(ctx, UserKey, user)
logger.Debug("User authenticated successfully",
zap.Any("user_id", userID),
zap.String("username", user.FirstName))
logger.Debug("authMiddleware End")
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) {
logger := logger.Get()
userID := r.Context().Value(UserIDKey)
logger.Debug("RequireAuth method start")
logger.Debug("Extracted user ID from token",
zap.Any("user_id", userID))
if userID == nil {
logger.Warn("Authentication required but no user ID in context")
http.Error(w, `{"error": "Authentication required"}`, http.StatusUnauthorized)
return
}
logger.Debug("User authenticated", zap.Any("user_id", userID))
logger.Debug("authMiddleware End")
next.ServeHTTP(w, r)
})
}
// GetUserFromContext получает пользователя из контекста
func GetUserFromContext(ctx context.Context) (*models.User, bool) {
logger := logger.Get()
user, ok := ctx.Value(UserKey).(*models.User)
logger.Debug("GetUserFromContext method")
logger.Debug("Extracted user ID from token",
zap.Any("user_id", user.ID))
if !ok {
logger.Debug("No user found in context")
} else {
logger.Debug("User retrieved from context",
zap.Any("user_id", user.ID),
zap.String("username", user.FirstName))
}
return user, ok
}