64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"dance-lessons-coach/pkg/greet"
|
|
"dance-lessons-coach/pkg/user"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
// AuthMiddleware handles JWT authentication and adds user to context
|
|
type AuthMiddleware struct {
|
|
authService user.AuthService
|
|
}
|
|
|
|
// NewAuthMiddleware creates a new authentication middleware
|
|
func NewAuthMiddleware(authService user.AuthService) *AuthMiddleware {
|
|
return &AuthMiddleware{
|
|
authService: authService,
|
|
}
|
|
}
|
|
|
|
// Middleware returns the authentication middleware function
|
|
func (m *AuthMiddleware) Middleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
|
|
// Extract Authorization header
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" {
|
|
// No authorization header, pass through with no user
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// Extract token from "Bearer <token>" format
|
|
const bearerPrefix = "Bearer "
|
|
if len(authHeader) < len(bearerPrefix) || authHeader[:len(bearerPrefix)] != bearerPrefix {
|
|
log.Trace().Ctx(ctx).Str("auth_header", authHeader).Msg("Invalid authorization header format")
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
token := authHeader[len(bearerPrefix):]
|
|
|
|
// Validate JWT token
|
|
validatedUser, err := m.authService.ValidateJWT(ctx, token)
|
|
if err != nil {
|
|
log.Trace().Ctx(ctx).Err(err).Msg("JWT validation failed")
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// Add user to context
|
|
ctxWithUser := context.WithValue(ctx, greet.UserContextKey, validatedUser)
|
|
r = r.WithContext(ctxWithUser)
|
|
|
|
// Continue to next handler
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|