Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

auth_middleware.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package middleware
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strings"
  6. "time"
  7. "git.x2erp.com/qdy/go-base/config"
  8. "git.x2erp.com/qdy/go-base/ctx"
  9. "git.x2erp.com/qdy/go-base/logger"
  10. "git.x2erp.com/qdy/go-base/types"
  11. )
  12. // 全局配置(单例)
  13. var appConfig config.IConfig
  14. // ResponseFormat 响应格式
  15. type ResponseFormat int
  16. const (
  17. FormatJSON ResponseFormat = iota
  18. FormatCSV
  19. )
  20. // JWTAuthMiddlewareInit 初始化中间件配置
  21. func JWTAuthMiddlewareInit(config config.IConfig) {
  22. appConfig = config
  23. }
  24. // JWT认证中间件(支持指定响应格式)
  25. func JWTAuthMiddleware(next http.Handler) http.Handler {
  26. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  27. // 从Header获取Authorization
  28. authHeader := r.Header.Get("Authorization")
  29. // 检查Authorization头是否存在
  30. if authHeader == "" {
  31. sendAuthError(w, "Authorization header is required", getResponseFormat(r))
  32. return
  33. }
  34. // 检查Bearer格式
  35. if !strings.HasPrefix(authHeader, "Bearer ") {
  36. sendAuthError(w, "Authorization header must start with 'Bearer '", getResponseFormat(r))
  37. return
  38. }
  39. token := strings.TrimPrefix(authHeader, "Bearer ")
  40. // 验证JWT令牌
  41. if !isValidToken(token) {
  42. sendAuthError(w, "Invalid token", getResponseFormat(r))
  43. return
  44. }
  45. //保存上下文
  46. // 创建LoggerContext(从token解析用户信息)
  47. requestContext := &ctx.RequestContext{
  48. ServiceName: appConfig.GetServiceConfig().ServiceName,
  49. InstanceName: appConfig.GetServiceConfig().InstanceName,
  50. TraceID: "trace_id-123", // 生成追踪ID
  51. TenantID: "tenant-123", // 从token解析
  52. UserID: "user-456", // 从token解析
  53. }
  54. if logger.IsDebug() {
  55. logger.DebugC(requestContext, "Before save requestContext: %+v", requestContext)
  56. }
  57. // 保存到请求
  58. r = ctx.SaveContext(r, requestContext)
  59. // 继续处理请求
  60. next.ServeHTTP(w, r)
  61. })
  62. }
  63. // 根据请求路径判断响应格式
  64. func getResponseFormat(r *http.Request) ResponseFormat {
  65. path := r.URL.Path
  66. // 判断是否为CSV接口(根据你的路由规则)
  67. if strings.Contains(path, "/csv") || strings.Contains(path, "/export") {
  68. return FormatCSV
  69. }
  70. // 默认返回JSON格式
  71. return FormatJSON
  72. }
  73. // 发送认证错误响应(根据格式)
  74. func sendAuthError(w http.ResponseWriter, message string, format ResponseFormat) {
  75. w.WriteHeader(http.StatusUnauthorized)
  76. switch format {
  77. case FormatCSV:
  78. w.Header().Set("Content-Type", "text/csv")
  79. w.Write([]byte("error,message\n"))
  80. w.Write([]byte("unauthorized," + message + "\n"))
  81. default:
  82. w.Header().Set("Content-Type", "application/json")
  83. json.NewEncoder(w).Encode(&types.QueryResult[map[string]interface{}]{
  84. Success: false,
  85. Error: message,
  86. Time: time.Now().Format(time.RFC3339),
  87. })
  88. }
  89. }
  90. // 验证令牌(需要根据实际项目实现)
  91. func isValidToken(token string) bool {
  92. // TODO: 实现真正的JWT验证逻辑
  93. // 暂时简化处理
  94. return token != ""
  95. }