15357fd3c0
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
138 lines
3.7 KiB
Go
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
|
|
}
|