Files
Go-Web-Template/server/middleware/cors.go
2026-04-23 15:29:07 +08:00

74 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"git.echol.cn/loser/Go-Web-Template/server/config"
"git.echol.cn/loser/Go-Web-Template/server/global"
"github.com/gin-gonic/gin"
"net/http"
)
// Cors 直接放行所有跨域请求并放行所有 OPTIONS 方法
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type, New-Token, New-Expires-At")
c.Header("Access-Control-Allow-Credentials", "true")
// 放行所有OPTIONS方法预检请求不应继续进入路由否则易落到 404
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}
// CorsByRules 按照配置处理跨域请求
func CorsByRules() gin.HandlerFunc {
// 放行全部
if global.GVA_CONFIG.Cors.Mode == "allow-all" {
return Cors()
}
return func(c *gin.Context) {
whitelist := checkCors(c.GetHeader("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 && global.GVA_CONFIG.Cors.Mode == "strict-whitelist" && !(c.Request.Method == "GET" && c.Request.URL.Path == "/health") {
c.AbortWithStatus(http.StatusForbidden)
return
}
// OPTIONS 预检:直接结束,避免继续匹配路由导致 404
if c.Request.Method == http.MethodOptions {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}
func checkCors(currentOrigin string) *config.CORSWhitelist {
for _, whitelist := range global.GVA_CONFIG.Cors.Whitelist {
// 遍历配置中的跨域头,寻找匹配项
if currentOrigin == whitelist.AllowOrigin {
return &whitelist
}
}
return nil
}