package middleware import ( "context" "fmt" "net/http" "strings" "crm-go/internal/handlers" "github.com/golang-jwt/jwt/v5" ) // AuthMiddleware 身份验证中间件 func AuthMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 登录接口和静态资源不需要认证 path := r.URL.Path if path == "/api/login" || !strings.HasPrefix(path, "/api/") { next.ServeHTTP(w, r) return } authHeader := r.Header.Get("Authorization") if authHeader == "" { http.Error(w, "未授权访问", http.StatusUnauthorized) return } // 解析 Bearer Token parts := strings.Split(authHeader, " ") if len(parts) != 2 || parts[0] != "Bearer" { http.Error(w, "无效的校验格式", http.StatusUnauthorized) return } tokenString := parts[1] token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("未预期的签名方法: %v", token.Header["alg"]) } return handlers.JWTSecret, nil }) if err != nil || !token.Valid { http.Error(w, "无效或过期的Token", http.StatusUnauthorized) return } // 将用户信息存入 context if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { ctx := context.WithValue(r.Context(), "username", claims["username"]) next.ServeHTTP(w, r.WithContext(ctx)) return } http.Error(w, "解析权限出错", http.StatusUnauthorized) }) }