From d9ba1cdf28e9faf0c360f7f7f10a848eb6fae577 Mon Sep 17 00:00:00 2001 From: Victor_Jay Date: Sat, 30 May 2026 23:38:42 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20Session=20?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E4=B8=8B=E5=B7=B2=E6=97=A0=E7=94=A8=E7=9A=84?= =?UTF-8?q?=20TokenVersion=20=E5=8D=B3=E6=97=B6=E5=90=8A=E9=94=80=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 UserRepo.IncrementTokenVersion/FindTokenVersion 方法 - 从 userAuthStore/userAdminStore 接口移除 IncrementTokenVersion - 删除 middleware.tokenVersionStore 接口(中间件不再查询 token_version) - auth_service: DeleteAccount/InvalidateSessions 仅调用 DestroyByUID - admin_service: UpdateUserStatus/ResetUserToken 仅调用 DestroyByUID - FindByIDForAuth/FindByIDUnscoped Select 移除 token_version 列 - 新架构下登出/改密/封禁统一走 sessionManager.DestroyByUID,无需 token_version --- internal/middleware/repository.go | 6 +----- internal/repository/user_repo.go | 23 +++-------------------- internal/service/admin_service.go | 14 ++++---------- internal/service/auth_service.go | 11 ++--------- internal/service/repository.go | 6 ++---- 5 files changed, 12 insertions(+), 48 deletions(-) diff --git a/internal/middleware/repository.go b/internal/middleware/repository.go index f28f1b5..3d65fb9 100644 --- a/internal/middleware/repository.go +++ b/internal/middleware/repository.go @@ -1,7 +1,3 @@ package middleware -// tokenVersionStore 最小接口:AuthMiddleware 不再需要此接口(session 替换 JWT) -// 保留占位,待后续清理 -type tokenVersionStore interface { - FindTokenVersion(userID uint) (int, error) -} +// repository.go: JWT tokenVersionStore 接口已随 Session 迁移移除,保留占位,后续清理。 diff --git a/internal/repository/user_repo.go b/internal/repository/user_repo.go index 323fa00..4f0af6c 100644 --- a/internal/repository/user_repo.go +++ b/internal/repository/user_repo.go @@ -74,28 +74,11 @@ func (r *UserRepo) ExistsByEmailExclude(email string, excludeUID uint) (bool, er return count > 0, err } -// IncrementTokenVersion 递增用户令牌版本,使所有已签发的 JWT 即时失效 -func (r *UserRepo) IncrementTokenVersion(userID uint) error { - return r.db.Unscoped().Model(&model.User{}).Where("uid = ?", userID). - UpdateColumn("token_version", gorm.Expr("token_version + 1")).Error -} - -// FindTokenVersion 按 UID 查询当前令牌版本(轻量查询,仅 SELECT token_version) -func (r *UserRepo) FindTokenVersion(userID uint) (int, error) { - var version int - err := r.db.Model(&model.User{}). - Select("token_version"). - Where("uid = ?", userID). - Scan(&version).Error - return version, err -} - -// FindByIDForAuth 认证专用查询:返回 uid/email/username/role/status/token_version +// FindByIDForAuth 认证专用查询:返回 uid/email/username/role/status // 比 FindByID 轻量(不查 avatar、bio 等无用字段),避免全量 SELECT * -// 使用默认 scope(排除软删除),locked 用户不可持有有效 JWT func (r *UserRepo) FindByIDForAuth(userID uint) (*model.User, error) { var user model.User - err := r.db.Select("uid", "email", "username", "role", "status", "token_version"). + err := r.db.Select("uid", "email", "username", "role", "status"). First(&user, userID).Error if err != nil { return nil, err @@ -106,7 +89,7 @@ func (r *UserRepo) FindByIDForAuth(userID uint) (*model.User, error) { // FindByIDUnscoped 管理后台专用:含软删除用户,用于解锁/封禁等操作 func (r *UserRepo) FindByIDUnscoped(userID uint) (*model.User, error) { var user model.User - err := r.db.Unscoped().Select("uid", "email", "username", "role", "status", "token_version", "deleted_at"). + err := r.db.Unscoped().Select("uid", "email", "username", "role", "status", "deleted_at"). First(&user, userID).Error if err != nil { return nil, err diff --git a/internal/service/admin_service.go b/internal/service/admin_service.go index 7ab641a..2f8bfd6 100644 --- a/internal/service/admin_service.go +++ b/internal/service/admin_service.go @@ -95,21 +95,15 @@ func (s *AdminService) UpdateUserStatus(operatorUID, targetUID uint, newStatus s return err } } - // 修改状态必须立刻让已有 session 失效 + 递增 token_version(向后兼容) - if err := s.sessionManager.DestroyByUID(target.ID); err != nil { - return err - } - return s.userRepo.IncrementTokenVersion(target.ID) + // 修改状态必须立刻让已有 session 失效 + return s.sessionManager.DestroyByUID(target.ID) }) } -// ResetUserToken 强制下线:销毁所有 session + 递增 token_version +// ResetUserToken 强制下线:销毁所有 session func (s *AdminService) ResetUserToken(operatorUID, targetUID uint) error { return s.checkAndOperate(operatorUID, targetUID, func(_ *model.User, target *model.User) error { - if err := s.sessionManager.DestroyByUID(target.ID); err != nil { - return err - } - return s.userRepo.IncrementTokenVersion(target.ID) + return s.sessionManager.DestroyByUID(target.ID) }) } diff --git a/internal/service/auth_service.go b/internal/service/auth_service.go index a4c529b..a4ad3d6 100644 --- a/internal/service/auth_service.go +++ b/internal/service/auth_service.go @@ -259,11 +259,7 @@ func (s *AuthService) DeleteAccount(userID uint, password, reason string) error return err } - // 删除所有 session + 递增 token_version(向后兼容) - if err := s.invalidateSessions(userID); err != nil { - return err - } - return s.userRepo.IncrementTokenVersion(userID) + return s.invalidateSessions(userID) } // invalidateSessions 销毁某用户的所有 session(内部方法) @@ -273,10 +269,7 @@ func (s *AuthService) invalidateSessions(userID uint) error { // InvalidateSessions 公开方法:销毁用户所有 session(供 admin 等外部调用) func (s *AuthService) InvalidateSessions(userID uint) error { - if err := s.invalidateSessions(userID); err != nil { - return err - } - return s.userRepo.IncrementTokenVersion(userID) + return s.sessionManager.DestroyByUID(userID) } // UpdateProfile 修改个人资料 diff --git a/internal/service/repository.go b/internal/service/repository.go index 566a6d6..5546036 100644 --- a/internal/service/repository.go +++ b/internal/service/repository.go @@ -2,14 +2,13 @@ package service import "metazone.cc/metalab/internal/model" -// userAuthStore AuthService 所需的最小仓储接口(ISP:8 个方法) +// userAuthStore AuthService 所需的最小仓储接口(ISP:7 个方法) type userAuthStore interface { ExistsByEmail(email string) (bool, error) Create(user *model.User) error FindByEmail(email string) (*model.User, error) FindByID(id uint) (*model.User, error) Update(user *model.User) error - IncrementTokenVersion(userID uint) error ExistsByUsername(username string) (bool, error) } @@ -18,7 +17,7 @@ type userTokenStore interface { FindByIDForAuth(userID uint) (*model.User, error) } -// userAdminStore AdminService 所需的最小仓储接口 +// userAdminStore AdminService 所需的最小仓储接口(ISP:7 个方法) type userAdminStore interface { CountSearchUsers(keyword, role, status string) (int64, error) SearchUsers(keyword, role, status string, offset, limit int) ([]model.User, error) @@ -27,7 +26,6 @@ type userAdminStore interface { SoftDelete(uid uint) error Restore(uid uint) error ExistsByEmailExclude(email string, excludeUID uint) (bool, error) - IncrementTokenVersion(userID uint) error } // postStore PostService 所需的最小仓储接口