refactor(auth): Implement lazy token parsing in UserID method

- Add jwt package import for token parsing
    - Add private ctxKeyTokenParsed constant to track parse status
    - Remove unused VBaseProvider variable
    - Rewrite UserID method with lazy token parsing logic
    - Check cached token status to avoid repeated parsing
    - Extract and parse token from request when needed
    - Validate token type is access token
    - Cache userID and parsed status in request context
master
veypi 4 weeks ago
parent 3ea5499532
commit 261dd9ffb0

@ -13,6 +13,7 @@ import (
"strings"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/libs/jwt"
"github.com/veypi/vbase/models"
"github.com/veypi/vigo"
pub "github.com/veypi/vigo/contrib/auth"
@ -33,6 +34,9 @@ const (
LevelAdmin = 7 // 111 管理员 (完全控制)
)
// ctxKeyTokenParsed 标记token是否已解析请求级别避免重复解析
const ctxKeyTokenParsed = "_token_parsed"
// PermFunc 权限检查函数类型
type PermFunc = pub.PermFunc
@ -44,9 +48,6 @@ var Factory = &authFactory{
apps: make(map[string]Provider),
}
// VBaseProvider vbase 自身的权限 Provider 实例
var VBaseProvider Provider
var _ pub.Provider = &vbaseProvider{}
func init() {
@ -98,10 +99,39 @@ type vbaseProvider struct {
// ========== Provider 接口实现 ==========
func (a *vbaseProvider) UserID(x *vigo.X) string {
if uid, ok := x.Get(CtxKeyUserID).(string); ok {
return uid
// 1. 检查是否已解析过(无论成功与否,避免重复解析)
if _, parsed := x.Get(ctxKeyTokenParsed).(bool); parsed {
if uid, ok := x.Get(CtxKeyUserID).(string); ok {
return uid
}
return ""
}
// 2. 惰性解析:从请求中提取 token
tokenStr := extractToken(x)
if tokenStr == "" {
x.Set(ctxKeyTokenParsed, true)
return ""
}
// 3. 解析并验证 token
claims, err := jwt.ParseToken(tokenStr)
if err != nil {
x.Set(ctxKeyTokenParsed, true)
return ""
}
// 确保是 access token
if !jwt.IsAccessToken(claims) {
x.Set(ctxKeyTokenParsed, true)
return ""
}
return ""
// 4. 设置到上下文中,供后续调用使用
x.Set(CtxKeyUserID, claims.UserID)
x.Set(ctxKeyTokenParsed, true)
return claims.UserID
}
// Grant 授予权限

Loading…
Cancel
Save