This commit is contained in:
toom1996
2026-08-26 10:45:21 +08:00
parent 3cf1368e68
commit 30c9f21da4
48 changed files with 3442 additions and 0 deletions

View File

@ -0,0 +1,55 @@
package middleware
import (
"net/http"
"strconv"
"strings"
"fashionapi/internal/config"
"github.com/gin-gonic/gin"
)
// CORS 跨域中间件,规则来自 yml 配置。
//
// allow_origins 为 ["*"] 时直接放行全部来源(与原项目行为一致);
// 配置为具体域名列表时,仅当请求 Origin 命中白名单才回写该 Origin,
// 这样生产环境可以收紧到指定域名而无需改代码。
func CORS(cfg config.CORSConfig) gin.HandlerFunc {
allowAll := len(cfg.AllowOrigins) == 0
allowed := make(map[string]struct{}, len(cfg.AllowOrigins))
for _, o := range cfg.AllowOrigins {
if o == "*" {
allowAll = true
}
allowed[o] = struct{}{}
}
methods := strings.Join(cfg.AllowMethods, ", ")
headers := strings.Join(cfg.AllowHeaders, ", ")
maxAge := strconv.Itoa(cfg.MaxAge)
return func(c *gin.Context) {
origin := c.GetHeader("Origin")
switch {
case allowAll:
c.Header("Access-Control-Allow-Origin", "*")
case origin != "":
if _, ok := allowed[origin]; ok {
c.Header("Access-Control-Allow-Origin", origin)
// 指定来源时必须声明 Vary,避免 CDN / 代理把响应错误地跨来源复用
c.Header("Vary", "Origin")
}
}
c.Header("Access-Control-Allow-Methods", methods)
c.Header("Access-Control-Allow-Headers", headers)
c.Header("Access-Control-Max-Age", maxAge)
// 预检请求直接结束,不进入业务逻辑
if c.Request.Method == http.MethodOptions {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}