package middleware import ( "awesomeProject/internal/common" jwtutil "awesomeProject/pkg/utils" "github.com/gin-gonic/gin" "net/http" "strings" ) // Whitelist 白名单路径(支持通配符) var Whitelist = []string{ "/back/file/**", "/back/login", } func CORSMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "*") c.Header("Access-Control-Allow-Headers", "*") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(http.StatusNoContent) return } c.Next() } } func JWTMiddleware(c *gin.Context) { // ✅ 1. 获取请求路径 path := c.Request.URL.Path if !strings.HasPrefix(path, "/back") { c.Next() return } // ✅ 2. 检查是否在白名单中 for _, rule := range Whitelist { if PathMatch(rule, path) { c.Next() return } } // ✅ 3. 从 Header 中提取 Token tokenString := c.GetHeader("token") if tokenString == "" { c.AbortWithStatusJSON(http.StatusOK, common.Error(401, "token无效")) return } // ✅ 4. 解析并验证 Token claims, err := jwtutil.ParseTokenToMap(tokenString) if err != nil { c.AbortWithStatusJSON(http.StatusOK, common.Error(401, "token无效")) return } // ✅ 5. Token 有效,继续处理 c.Set("tokenMap", claims) c.Next() } // PathMatch 判断请求路径是否匹配白名单中的通配符规则 func PathMatch(pattern, path string) bool { if pattern == path { return true } if len(pattern) > 0 && pattern[0] == '/' { pattern = pattern[1:] } if len(path) > 0 && path[0] == '/' { path = path[1:] } patternParts := strings.Split(pattern, "/") pathParts := strings.Split(path, "/") if len(patternParts) > len(pathParts) { return false } for i := 0; i < len(patternParts); i++ { p := patternParts[i] if p == "**" { // 匹配任意多级路径 return true } else if p == "*" { // 匹配单级路径 if i == len(patternParts)-1 { return true } continue } else if p != pathParts[i] { return false } } // 如果模式完全匹配路径的前缀 return len(patternParts) == len(pathParts) }