// Package middleware 提供请求日志、错误恢复、认证/授权与审计等 HTTP 中间件。 package middleware import ( "context" "net" "net/http" "strings" "git.yeij.top/AskaEth/Scoreboard/server/internal/auth" ) type ctxKey int const ( ctxKeyUser ctxKey = iota ctxKeyRequestID ctxKeyAudit ) // User 返回当前请求的身份;未经 Authenticate 中间件时是 guest。 func User(ctx context.Context) *auth.User { if u, ok := ctx.Value(ctxKeyUser).(*auth.User); ok { return u } return &auth.User{Role: auth.RoleGuest} } // WithUser 把身份写入 context,供测试或非标准链路使用。 func WithUser(ctx context.Context, u *auth.User) context.Context { return context.WithValue(ctx, ctxKeyUser, u) } // GetRequestID 返回本次请求的 request_id。 func GetRequestID(ctx context.Context) string { if v, ok := ctx.Value(ctxKeyRequestID).(string); ok { return v } return "" } // ClientIP 从代理头或连接地址解析客户端 IP。 func ClientIP(r *http.Request) string { if xff := r.Header.Get("X-Forwarded-For"); xff != "" { if first := strings.TrimSpace(strings.Split(xff, ",")[0]); first != "" { return first } } if rip := strings.TrimSpace(r.Header.Get("X-Real-IP")); rip != "" { return rip } host, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { return r.RemoteAddr } return host }