| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package middleware
-
- import (
- "encoding/json"
- "net/http"
- "strings"
- "time"
-
- "git.x2erp.com/qdy/go-base/config"
- "git.x2erp.com/qdy/go-base/ctx"
- "git.x2erp.com/qdy/go-base/logger"
- "git.x2erp.com/qdy/go-base/model/response"
- )
-
- // 全局配置(单例)
- var appConfig config.IConfig
-
- // ResponseFormat 响应格式
- type ResponseFormat int
-
- const (
- FormatJSON ResponseFormat = iota
- FormatCSV
- )
-
- // JWTAuthMiddlewareInit 初始化中间件配置
- func JWTAuthMiddlewareInit(config config.IConfig) {
- appConfig = config
- }
-
- // JWT认证中间件(支持指定响应格式)
- func JWTAuthMiddleware(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- // 从Header获取Authorization
- authHeader := r.Header.Get("Authorization")
-
- // 检查Authorization头是否存在
- if authHeader == "" {
- sendAuthError(w, "Authorization header is required", getResponseFormat(r))
- return
- }
-
- // 检查Bearer格式
- if !strings.HasPrefix(authHeader, "Bearer ") {
- sendAuthError(w, "Authorization header must start with 'Bearer '", getResponseFormat(r))
- return
- }
-
- token := strings.TrimPrefix(authHeader, "Bearer ")
-
- // 验证JWT令牌
- if !isValidToken(token) {
- sendAuthError(w, "Invalid token", getResponseFormat(r))
- return
- }
-
- //保存上下文
- // 创建LoggerContext(从token解析用户信息)
- requestContext := &ctx.RequestContext{
- ServiceName: appConfig.GetServiceConfig().ServiceName,
- InstanceName: appConfig.GetServiceConfig().InstanceName,
- TraceID: "trace_id-123", // 生成追踪ID
- TenantID: "tenant-123", // 从token解析
- UserID: "user-456", // 从token解析
- }
-
- if logger.IsDebug() {
- logger.DebugC(requestContext, "Before save requestContext: %+v", requestContext)
- }
-
- // 保存到请求
- r = ctx.SaveContext(r, requestContext)
- // 继续处理请求
- next.ServeHTTP(w, r)
- })
- }
-
- // 根据请求路径判断响应格式
- func getResponseFormat(r *http.Request) ResponseFormat {
- path := r.URL.Path
-
- // 判断是否为CSV接口(根据你的路由规则)
- if strings.Contains(path, "/csv") || strings.Contains(path, "/export") {
- return FormatCSV
- }
-
- // 默认返回JSON格式
- return FormatJSON
- }
-
- // 发送认证错误响应(根据格式)
- func sendAuthError(w http.ResponseWriter, message string, format ResponseFormat) {
- w.WriteHeader(http.StatusUnauthorized)
-
- switch format {
- case FormatCSV:
- w.Header().Set("Content-Type", "text/csv")
- w.Write([]byte("error,message\n"))
- w.Write([]byte("unauthorized," + message + "\n"))
- default:
- w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(&response.QueryResult[map[string]interface{}]{
- Success: false,
- Error: message,
- Time: time.Now().Format(time.RFC3339),
- })
- }
- }
-
- // 验证令牌(需要根据实际项目实现)
- func isValidToken(token string) bool {
- // TODO: 实现真正的JWT验证逻辑
- // 暂时简化处理
- return token != ""
- }
|