whatapp-go-pvnet/backend/middleware/middleware.go
2025-05-09 10:14:22 +02:00

101 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
"github.com/golang-jwt/jwt"
)
var secretKey = []byte("secret-key")
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var tokenString string
// 1. Vérifie Authorization: Bearer ...
if authHeader := r.Header.Get("Authorization"); strings.HasPrefix(authHeader, "Bearer ") {
tokenString = strings.TrimPrefix(authHeader, "Bearer ")
}
// 2. Vérifie le cookie si pas de header
if tokenString == "" {
if cookie, err := r.Cookie("token"); err == nil {
tokenString = cookie.Value
}
}
// 3. Vérifie le body JSON uniquement si POST ou PUT
if tokenString == "" && r.Method == http.MethodPost || r.Method == http.MethodPut {
if strings.Contains(r.Header.Get("Content-Type"), "application/json") {
bodyCopy, _ := io.ReadAll(r.Body)
var bodyMap map[string]interface{}
if err := json.Unmarshal(bodyCopy, &bodyMap); err == nil {
if val, ok := bodyMap["token"].(string); ok {
tokenString = val
// restaure le body
r.Body = io.NopCloser(bytes.NewReader(bodyCopy))
}
}
}
}
if tokenString == "" {
http.Error(w, "Token manquant", http.StatusUnauthorized)
return
}
// ✅ Vérifie et parse le token
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("méthode signature invalide")
}
return secretKey, nil
})
if err != nil || !token.Valid {
http.Error(w, "Token invalide", http.StatusUnauthorized)
return
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
http.Error(w, "Claims invalides", http.StatusUnauthorized)
return
}
// vérifie lexpiration
if exp, ok := claims["exp"].(float64); ok {
if time.Now().Unix() > int64(exp) {
http.Error(w, "Token expiré", http.StatusUnauthorized)
return
}
}
// récupère lidentifiant
ssoid, ok := claims["username"].(string)
if !ok {
http.Error(w, "SSOID manquant", http.StatusUnauthorized)
return
}
// injection dans le contexte
ctx := context.WithValue(r.Context(), "ssoid", ssoid)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// helper pour remarshal le JSON quand il est relu après parse
func mustMarshal(data map[string]interface{}) []byte {
b, _ := json.Marshal(data)
return b
}