package middleware import ( "context" "log/slog" "net/http" "github.com/golang-jwt/jwt/v5" ) const EmailKey contextKey = "email" func AuthMiddleware(logger *slog.Logger, jwtKey []byte) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("token") if err == http.ErrNoCookie { logger.WarnContext(r.Context(), "token not provided") w.WriteHeader(http.StatusUnauthorized) return } if err != nil { logger.ErrorContext(r.Context(), err.Error()) w.WriteHeader(http.StatusInternalServerError) return } tokenString := cookie.Value token, err := jwt.Parse(tokenString, func(t *jwt.Token) (any, error) { return jwtKey, nil }) if !token.Valid { logger.WarnContext(r.Context(), err.Error()) w.WriteHeader(http.StatusUnauthorized) return } if err != nil { logger.ErrorContext(r.Context(), err.Error()) w.WriteHeader(http.StatusInternalServerError) return } email, err := token.Claims.GetSubject() if err != nil { logger.ErrorContext(r.Context(), err.Error()) w.WriteHeader(http.StatusInternalServerError) return } ctx := context.WithValue(r.Context(), EmailKey, email) newReq := r.WithContext(ctx) next.ServeHTTP(w, newReq) }) } }