65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package middlewares
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"quyun/v2/app/errorx"
|
|
"quyun/v2/pkg/consts"
|
|
"quyun/v2/providers/jwt"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
func shouldSkipUserJWTAuth(path string, method string) bool {
|
|
// 仅对明确的公开接口放行,避免误伤其它路径。
|
|
if method != fiber.MethodPost {
|
|
return false
|
|
}
|
|
|
|
p := strings.TrimSuffix(path, "/")
|
|
switch p {
|
|
case "/v1/auth/login", "/v1/auth/register":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// UserAuth 为平台通用(非租户域)接口提供 JWT 校验,并写入 claims 到 ctx locals。
|
|
func (f *Middlewares) UserAuth(c fiber.Ctx) error {
|
|
if shouldSkipUserJWTAuth(c.Path(), c.Method()) {
|
|
f.log.Debug("middlewares.user.auth.skipped")
|
|
return c.Next()
|
|
}
|
|
|
|
authHeader := c.Get(jwt.HttpHeader)
|
|
if authHeader == "" {
|
|
f.log.Info("middlewares.user.auth.missing_token")
|
|
return errorx.ErrTokenMissing
|
|
}
|
|
|
|
claims, err := f.jwt.Parse(authHeader)
|
|
if err != nil {
|
|
f.log.WithError(err).Warn("middlewares.user.auth.invalid_token")
|
|
switch err {
|
|
case jwt.TokenExpired:
|
|
return errorx.ErrTokenExpired
|
|
case jwt.TokenMalformed, jwt.TokenNotValidYet, jwt.TokenInvalid:
|
|
return errorx.ErrTokenInvalid
|
|
default:
|
|
return errorx.ErrTokenInvalid
|
|
}
|
|
}
|
|
if claims.UserID == 0 {
|
|
f.log.Warn("middlewares.user.auth.missing_user_id")
|
|
return errorx.ErrTokenInvalid
|
|
}
|
|
|
|
f.log.WithFields(map[string]any{
|
|
"user_id": claims.UserID,
|
|
}).Info("middlewares.user.auth.ok")
|
|
|
|
c.Locals(consts.CtxKeyClaims, claims)
|
|
return c.Next()
|
|
}
|