5.2 中间件开发
中间件原理
go
// 中间件本质
type Middleware func(http.Handler) http.Handler
// Gin 中间件
type GinMiddleware func(*gin.Context)
// 执行流程:
// 请求 -> Middleware1 -> Middleware2 -> Handler -> Middleware2 -> Middleware1 -> 响应自定义中间件
go
// 基础中间件
func SimpleMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 请求前
c.Next()
// 请求后
}
}
// 日志中间件
func LoggerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
latency := time.Since(start)
fmt.Printf("[%s] %s %d %v\n", c.Request.Method, c.Request.URL.Path, c.Writer.Status(), latency)
}
}
// 认证中间件
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.AbortWithStatusJSON(401, gin.H{"error": "未提供 token"})
return
}
if !validateToken(token) {
c.AbortWithStatusJSON(401, gin.H{"error": "token 无效"})
return
}
c.Set("userID", "123")
c.Next()
}
}
// 限流中间件
func RateLimitMiddleware(maxReqs int, window time.Duration) gin.HandlerFunc {
requests := make(map[string][]time.Time)
return func(c *gin.Context) {
ip := c.ClientIP()
now := time.Now()
// 清理过期记录
var validReqs []time.Time
for _, t := range requests[ip] {
if t.After(now.Add(-window)) {
validReqs = append(validReqs, t)
}
}
// 检查是否超限
if len(validReqs) >= maxReqs {
c.AbortWithStatusJSON(429, gin.H{"error": "请求过于频繁"})
return
}
validReqs = append(validReqs, now)
requests[ip] = validReqs
c.Next()
}
}CORS 中间件
go
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}
// 使用 gin-contrib/cors
import "github.com/gin-contrib/cors"
config := cors.DefaultConfig()
config.AllowOrigins = []string{"http://localhost:3000"}
r.Use(cors.New(config))