45 lines
1.1 KiB
Go
45 lines
1.1 KiB
Go
|
|
package middleware
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"net/http"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"floorvisualizer/internal/service"
|
||
|
|
)
|
||
|
|
|
||
|
|
type contextKey string
|
||
|
|
|
||
|
|
const userIDKey contextKey = "userID"
|
||
|
|
|
||
|
|
func RequireAuth(authSvc *service.AuthService) func(http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return func(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
authHeader := r.Header.Get("Authorization")
|
||
|
|
if authHeader == "" {
|
||
|
|
http.Error(w, `{"error":"missing authorization header"}`, http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
parts := strings.SplitN(authHeader, " ", 2)
|
||
|
|
if len(parts) != 2 || !strings.EqualFold(parts[0], "bearer") {
|
||
|
|
http.Error(w, `{"error":"invalid authorization format"}`, http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
claims, err := authSvc.ParseToken(parts[1])
|
||
|
|
if err != nil {
|
||
|
|
http.Error(w, `{"error":"invalid or expired token"}`, http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
ctx := context.WithValue(r.Context(), userIDKey, claims.UserID)
|
||
|
|
next(w, r.WithContext(ctx))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func UserID(ctx context.Context) string {
|
||
|
|
if v, ok := ctx.Value(userIDKey).(string); ok {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
return ""
|
||
|
|
}
|