首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"cloudnest/internal/pkg/logger"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// allowedOrigins defines the list of allowed origins for development.
|
||||
// In production, this should be loaded from configuration.
|
||||
// allowedOrigins 定义开发环境允许的源列表。生产环境应从配置加载。
|
||||
var allowedOrigins = []string{
|
||||
"http://localhost:8081",
|
||||
"https://localhost:8081",
|
||||
"http://127.0.0.1:8081",
|
||||
"https://127.0.0.1:8081",
|
||||
}
|
||||
|
||||
// isAllowedOrigin checks if the given origin is in the allowed list.
|
||||
// isAllowedOrigin 检查给定的源是否在允许列表中。
|
||||
func isAllowedOrigin(origin string) bool {
|
||||
for _, o := range allowedOrigins {
|
||||
if strings.EqualFold(o, origin) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CORS creates a middleware that handles Cross-Origin Resource Sharing.
|
||||
// CORS 创建一个处理跨域资源共享(CORS)的中间件。
|
||||
//
|
||||
// This middleware sets the necessary headers to allow cross-origin requests,
|
||||
// including the allowed origins, methods, and headers.
|
||||
//
|
||||
// Important:
|
||||
// - For requests with Authorization header, the browser requires the
|
||||
// Access-Control-Allow-Origin header to be a specific origin, not "*".
|
||||
// - This middleware dynamically sets the origin to match the request's
|
||||
// Origin header, which allows cross-origin requests with credentials.
|
||||
// - In production, you should restrict allowed origins to specific domains.
|
||||
//
|
||||
// 此中间件设置必要的头部以允许跨域请求,包括允许的来源、方法和头部。
|
||||
//
|
||||
// 重要:
|
||||
// - 对于带有 Authorization 头部的请求,浏览器要求 Access-Control-Allow-Origin
|
||||
// 必须是具体的源,不能是 "*"。
|
||||
// - 此中间件动态设置源以匹配请求的 Origin 头部,允许带凭据的跨域请求。
|
||||
// - 在生产环境中,应将允许的源限制为特定域名。
|
||||
//
|
||||
// Returns:
|
||||
// - gin.HandlerFunc: The CORS middleware handler.
|
||||
//
|
||||
// 返回值:
|
||||
// - gin.HandlerFunc: CORS 中间件处理器。
|
||||
func CORS() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// Get the Origin header from the request
|
||||
// 从请求中获取 Origin 头部
|
||||
origin := c.Request.Header.Get("Origin")
|
||||
|
||||
logger.Info("CORS middleware invoked",
|
||||
"method", c.Request.Method,
|
||||
"path", c.Request.URL.Path,
|
||||
"origin", origin,
|
||||
)
|
||||
|
||||
// Determine the allowed origin to return.
|
||||
// If the origin is in our allowed list, echo it back.
|
||||
// Otherwise, for development, also echo it back to be permissive.
|
||||
// In production, you should reject unallowed origins.
|
||||
//
|
||||
// 确定要返回的允许源。如果在允许列表中,则回显。
|
||||
// 开发环境下也回显其他源以方便调试。生产环境应拒绝未允许的源。
|
||||
allowedOrigin := ""
|
||||
if origin != "" {
|
||||
if isAllowedOrigin(origin) {
|
||||
allowedOrigin = origin
|
||||
} else {
|
||||
// Development fallback: allow any origin for easier local testing
|
||||
// 开发环境回退:允许任何源以方便本地测试
|
||||
allowedOrigin = origin
|
||||
logger.Warn("CORS request from unknown origin",
|
||||
"origin", origin,
|
||||
"path", c.Request.URL.Path,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Set Access-Control-Allow-Origin to the request's origin
|
||||
// This allows cross-origin requests with Authorization header
|
||||
// 将 Access-Control-Allow-Origin 设置为请求的源
|
||||
// 这允许带 Authorization 头部的跨域请求
|
||||
if allowedOrigin != "" {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", allowedOrigin)
|
||||
}
|
||||
|
||||
// Allow credentials (cookies, Authorization headers)
|
||||
// 允许凭据(cookies、Authorization 头部)
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
// Allow common HTTP methods
|
||||
// 允许常用 HTTP 方法
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
|
||||
|
||||
// Allow common headers including Authorization
|
||||
// 允许常用头部,包括 Authorization
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Accept, Origin, X-Request-ID")
|
||||
|
||||
// Expose headers to the client
|
||||
// 暴露头部给客户端
|
||||
c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Disposition, Content-Length, X-Request-ID")
|
||||
|
||||
// Handle OPTIONS preflight requests
|
||||
// 处理 OPTIONS 预检请求
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
logger.Info("CORS handling OPTIONS preflight", "origin", origin, "path", c.Request.URL.Path)
|
||||
c.AbortWithStatus(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user