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

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