package middleware import ( "net/http" "strings" "github.com/gin-gonic/gin" ) // CORS 跨域中间件 // 这是同源应用(前端、后台、API 都在同一服务),因此默认不对外部跨域放行。 // 仅允许本站自身的 Origin 访问,避免任意外部站点的跨域请求读取或携带凭证。 func CORS() gin.HandlerFunc { return func(c *gin.Context) { origin := c.GetHeader("Origin") host := c.Request.Host // 同源请求或没有 Origin 的请求(curl 等)直接放行 if origin == "" || strings.Contains(origin, "://"+host) { // 仍允许同源反射,方便调试 if origin != "" { c.Header("Access-Control-Allow-Origin", origin) c.Header("Vary", "Origin") } if c.Request.Method == http.MethodOptions { c.AbortWithStatus(http.StatusNoContent) return } c.Next() return } // 非同源且非本站:拒绝携带凭证的跨域请求 if c.Request.Method == http.MethodOptions { // 预检请求直接拒绝 c.AbortWithStatus(http.StatusForbidden) return } // 允许无凭证的只读公开请求,但不返回 Allow-Origin,浏览器会拦截跨域读取 if c.Request.Method == http.MethodGet { c.Next() return } // 写操作(POST/PUT/DELETE)来自外部站点的跨域请求:拦截 c.AbortWithStatus(http.StatusForbidden) } }