package middleware import ( "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/keyauth" "go.uber.org/zap" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/response" "github.com/break/junhong_cmp_fiber/pkg/validator" ) // KeyAuth 创建基于 Redis 的令牌认证中间件 func KeyAuth(v *validator.TokenValidator, logger *zap.Logger) fiber.Handler { return keyauth.New(keyauth.Config{ KeyLookup: "header:token", Validator: func(c *fiber.Ctx, key string) (bool, error) { // 验证令牌 userID, err := v.Validate(key) if err != nil { // 获取请求 ID 用于日志 requestID := "" if rid := c.Locals(constants.ContextKeyRequestID); rid != nil { requestID = rid.(string) } logger.Warn("令牌验证失败", zap.String("request_id", requestID), zap.Error(err), ) return false, err } // 在上下文中存储用户 ID c.Locals(constants.ContextKeyUserID, userID) return true, nil }, ErrorHandler: func(c *fiber.Ctx, err error) error { // 将错误映射到统一响应格式 switch err { case keyauth.ErrMissingOrMalformedAPIKey: return response.Error(c, 400, errors.CodeMissingToken, errors.GetMessage(errors.CodeMissingToken, "zh")) case errors.ErrInvalidToken: return response.Error(c, 400, errors.CodeInvalidToken, errors.GetMessage(errors.CodeInvalidToken, "zh")) case errors.ErrRedisUnavailable: return response.Error(c, 503, errors.CodeAuthServiceUnavailable, errors.GetMessage(errors.CodeAuthServiceUnavailable, "zh")) default: return response.Error(c, 500, errors.CodeInternalError, errors.GetMessage(errors.CodeInternalError, "zh")) } }, }) }