refactor(middleware): 重构权限中间件以统一上下文管理
- 引入 utils.UserContext 结构体统一管理用户上下文信息 - 创建新的上下文键 UserContent 用于存储用户信息 - 移除分散的 context.Value 调用,改用结构化数据传递 - 修正 context.WithValue 返回值未被正确使用的逻辑错误 - 更新 logout_logic.go 中的 Token 和用户ID获取方式 - 删除冗余的 Token 清理和提取函数 - 新增 context_util.go 文件提供上下文工具方法 - 简化 logout 接口中的上下文数据访问逻辑
This commit is contained in:
parent
a9f61e0fb2
commit
5aabd0a3a8
|
|
@ -3,14 +3,14 @@ package user
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/saas-mingyang/mingyang-admin-common/i18n"
|
||||
"mingyang-admin-app-api/internal/svc"
|
||||
"mingyang-admin-app-api/internal/types"
|
||||
"mingyang-admin-app-rpc/types/app"
|
||||
"net/http"
|
||||
"mingyang-admin-app-rpc/utils"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
|
@ -37,16 +37,20 @@ func (l *LogoutLogic) Logout() (resp *types.BaseMsgResp, err error) {
|
|||
n := runtime.Stack(buf, false)
|
||||
l.Logger.Infof("Logout call stack:\n%s", buf[:n])
|
||||
|
||||
token := l.getTokenFromContext()
|
||||
l.Infof("Starting Logout RPC call at: %v", time.Now())
|
||||
userContent, err := l.getTokenFromContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l.Info("UserContent: %v", userContent)
|
||||
|
||||
l.Infof("Starting Logout RPC call at: %v", time.Now())
|
||||
// 记录goroutine ID
|
||||
goID := getGoroutineID()
|
||||
l.Logger.Infof("Goroutine ID: %d", goID)
|
||||
|
||||
_, err = l.svcCtx.AppRpc.LogoutUser(l.ctx, &app.UserToken{
|
||||
AccessToken: token,
|
||||
UserId: l.getUserIDFromContext(),
|
||||
AccessToken: userContent.Token,
|
||||
UserId: userContent.UserID,
|
||||
})
|
||||
|
||||
l.Logger.Infof("Finished Logout RPC call at: %v", time.Now())
|
||||
|
|
@ -68,50 +72,12 @@ func getGoroutineID() uint64 {
|
|||
}
|
||||
|
||||
// 从上下文中获取 Token
|
||||
func (l *LogoutLogic) getTokenFromContext() string {
|
||||
// 尝试不同的 key 从上下文中获取 Token
|
||||
keys := []string{"token", "access_token", "jwt_token", "auth_token"}
|
||||
|
||||
for _, key := range keys {
|
||||
if token, ok := l.ctx.Value(key).(string); ok && token != "" {
|
||||
return l.cleanToken(token)
|
||||
}
|
||||
func (l *LogoutLogic) getTokenFromContext() (*utils.UserContext, error) {
|
||||
requestContext := utils.GetRequestContext(l.ctx)
|
||||
if requestContext == nil {
|
||||
return nil, errors.New("invalid request context")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 清理 Token 字符串,移除 "Bearer " 前缀
|
||||
func (l *LogoutLogic) cleanToken(token string) string {
|
||||
if token == "" {
|
||||
return ""
|
||||
}
|
||||
token = strings.TrimSpace(token)
|
||||
// 移除 "Bearer " 前缀
|
||||
if strings.HasPrefix(strings.ToLower(token), "bearer ") {
|
||||
token = token[7:]
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
||||
// 从 Authorization Header 中提取 Token
|
||||
func (l *LogoutLogic) extractTokenFromAuthHeader(ctx context.Context) string {
|
||||
// 尝试从请求上下文获取 Request 对象
|
||||
if req, ok := ctx.Value("http_request").(*http.Request); ok {
|
||||
authHeader := req.Header.Get("Authorization")
|
||||
if authHeader != "" {
|
||||
return l.cleanToken(authHeader)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 从上下文中获取用户ID
|
||||
func (l *LogoutLogic) getUserIDFromContext() uint64 {
|
||||
// 在AuthMiddleware中,我们将用户ID放入了context
|
||||
if userID, ok := l.ctx.Value("userId").(uint64); ok {
|
||||
return userID
|
||||
}
|
||||
return 0
|
||||
return requestContext, nil
|
||||
}
|
||||
|
||||
// 获取 Token 过期时间
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err erro
|
|||
RefreshTokenExpires: token.RefreshTokenExpires.Seconds,
|
||||
},
|
||||
UserInfo: &types.UserInfo{
|
||||
BaseIDInfo: types.BaseIDInfo{
|
||||
Id: user.Id,
|
||||
},
|
||||
Username: user.Username,
|
||||
NickName: user.NickName,
|
||||
Avatar: user.Avatar,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"mingyang-admin-app-api/internal/types"
|
||||
"mingyang-admin-app-rpc/appclient"
|
||||
"mingyang-admin-app-rpc/types/app"
|
||||
"mingyang-admin-app-rpc/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -109,20 +110,19 @@ func (m *AuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
|||
|
||||
// 创建新的上下文,包含 Token 和用户信息
|
||||
ctx := r.Context()
|
||||
ctx = context.WithValue(ctx, "token", fromToken)
|
||||
ctx = context.WithValue(ctx, "userId", token.UserId)
|
||||
ctx = context.WithValue(ctx, "tokenClaims", token)
|
||||
|
||||
// 获取客户端 IP
|
||||
clientIP := getClientIP(r)
|
||||
ctx = context.WithValue(ctx, "client_ip", clientIP)
|
||||
|
||||
// 获取 User-Agent
|
||||
userAgent := r.UserAgent()
|
||||
ctx = context.WithValue(ctx, "user_agent", userAgent)
|
||||
|
||||
// 构建请求信息
|
||||
content := &utils.UserContext{
|
||||
Token: fromToken,
|
||||
UserID: token.UserId,
|
||||
TokenClaims: token,
|
||||
ClientIP: getClientIP(r),
|
||||
UserAgent: r.UserAgent(),
|
||||
}
|
||||
// 修正:必须接收 context.WithValue 的返回值
|
||||
newContent := context.WithValue(ctx, utils.UserContent, content)
|
||||
// 将新上下文设置到请求中
|
||||
r = r.WithContext(ctx)
|
||||
r = r.WithContext(newContent)
|
||||
|
||||
// 调用下一个处理器
|
||||
next(w, r)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
package server
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"mingyang-admin-app-rpc/types/app"
|
||||
)
|
||||
|
||||
const (
|
||||
UserContent = "userContent"
|
||||
)
|
||||
|
||||
// UserContext RequestContext 请求上下文信息(API 和 RPC 共享)
|
||||
type UserContext struct {
|
||||
Token string // 原始 token 字符串
|
||||
UserID uint64 // 用户ID
|
||||
TokenClaims *app.AuthInfoResp // token 解析后的 claims
|
||||
ClientIP string // 客户端IP
|
||||
UserAgent string // User-Agent
|
||||
}
|
||||
|
||||
// GetRequestContext 从上下文获取请求上下文(RPC 层)
|
||||
// 从上下文获取请求上下文
|
||||
func GetRequestContext(ctx context.Context) *UserContext {
|
||||
value := ctx.Value(UserContent)
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
reqCtx, ok := value.(*UserContext)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return reqCtx
|
||||
}
|
||||
Loading…
Reference in New Issue