54 lines
1.7 KiB
Go
54 lines
1.7 KiB
Go
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"))
|
|
}
|
|
},
|
|
})
|
|
}
|