package middleware import ( "net/http" "github.com/gin-gonic/gin" ) // GinCORSWhitelist Gin CORS白名单配置 type GinCORSWhitelist struct { AllowOrigin string AllowHeaders string AllowMethods string ExposeHeaders string AllowCredentials bool } // GinCORSConfig Gin CORS配置 type GinCORSConfig struct { // Mode 模式: allow-all, whitelist, strict-whitelist Mode string Whitelist []GinCORSWhitelist } // 全局CORS配置 var ginCorsConfig *GinCORSConfig // SetGinCORSConfig 设置Gin CORS配置 func SetGinCORSConfig(cfg *GinCORSConfig) { ginCorsConfig = cfg } // CorsByRules 按照配置处理跨域请求(与 kra 保持一致) func CorsByRules() gin.HandlerFunc { // 放行全部 if ginCorsConfig == nil || ginCorsConfig.Mode == "allow-all" { return Cors() } return func(c *gin.Context) { origin := c.GetHeader("origin") whitelist := checkGinCors(origin) // 通过检查, 添加请求头 if whitelist != nil { c.Header("Access-Control-Allow-Origin", whitelist.AllowOrigin) c.Header("Access-Control-Allow-Headers", whitelist.AllowHeaders) c.Header("Access-Control-Allow-Methods", whitelist.AllowMethods) c.Header("Access-Control-Expose-Headers", whitelist.ExposeHeaders) if whitelist.AllowCredentials { c.Header("Access-Control-Allow-Credentials", "true") } } // 严格白名单模式且未通过检查,直接拒绝处理请求 if whitelist == nil && ginCorsConfig.Mode == "strict-whitelist" { // 健康检查放行 if !(c.Request.Method == "GET" && c.Request.URL.Path == "/health") { c.AbortWithStatus(http.StatusForbidden) return } } else { // 非严格白名单模式,无论是否通过检查均放行所有 OPTIONS 方法 if c.Request.Method == http.MethodOptions { c.AbortWithStatus(http.StatusNoContent) return } } // 处理请求 c.Next() } } func checkGinCors(currentOrigin string) *GinCORSWhitelist { if ginCorsConfig == nil { return nil } for _, whitelist := range ginCorsConfig.Whitelist { // 遍历配置中的跨域头,寻找匹配项 if currentOrigin == whitelist.AllowOrigin { return &whitelist } } return nil }