diff --git a/api/internal/logic/user/logout_logic.go b/api/internal/logic/user/logout_logic.go index 957e6bd..63420c2 100644 --- a/api/internal/logic/user/logout_logic.go +++ b/api/internal/logic/user/logout_logic.go @@ -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 过期时间 diff --git a/api/internal/logic/user_public/login_logic.go b/api/internal/logic/user_public/login_logic.go index 2e41049..1027d05 100644 --- a/api/internal/logic/user_public/login_logic.go +++ b/api/internal/logic/user_public/login_logic.go @@ -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, diff --git a/api/internal/middleware/authority_middleware.go b/api/internal/middleware/authority_middleware.go index f07798b..16a2dfc 100644 --- a/api/internal/middleware/authority_middleware.go +++ b/api/internal/middleware/authority_middleware.go @@ -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) diff --git a/api/internal/server/user_content_server.go b/api/internal/server/user_content_server.go new file mode 100644 index 0000000..abb4e43 --- /dev/null +++ b/api/internal/server/user_content_server.go @@ -0,0 +1 @@ +package server diff --git a/rpc/utils/context_util.go b/rpc/utils/context_util.go new file mode 100644 index 0000000..a2536e2 --- /dev/null +++ b/rpc/utils/context_util.go @@ -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 +}