From fb94ce60aeb9823ab6222332ac9dd0c189478750 Mon Sep 17 00:00:00 2001 From: Victor_Jay Date: Sat, 30 May 2026 21:10:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BB=B4=E6=8A=A4=E6=9C=9F=E9=97=B4?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=B8=80=E5=BE=8B=E8=BF=94=E5=9B=9E=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E6=8F=90=E7=A4=BA=EF=BC=8C=E4=B8=8D=E6=B3=84=E9=9C=B2?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 维护检查提前到 FindByEmail 之后、所有状态检查之前 - 非站长账号(不存在/已封禁/已锁定等)统一走模拟 bcrypt 防时序 → 返回维护提示 - 站长角色正常通过,走完整登录流程 - 旧实现:维护检查在 banned/locked/deleted 之后,会泄露账号状态 --- internal/service/auth_service.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/internal/service/auth_service.go b/internal/service/auth_service.go index efc6e87..0e8888d 100644 --- a/internal/service/auth_service.go +++ b/internal/service/auth_service.go @@ -126,13 +126,24 @@ func (s *AuthService) Register(req model.RegisterRequest, regIP string) (string, } // Login 登录 -// 流程:按邮箱查找 → 已注销则验证密码后要求二次确认 → 检查状态 → 验证密码 → 记录登录 IP/时间 → access JWT + refresh JWT -// 防时序攻击:邮箱不存在时仍执行完整 bcrypt 比对 +// 流程:按邮箱查找 → 维护期间非站长统一拦截(模拟 bcrypt 防时序)→ 状态检查 → 验证密码 → 签发 token // rememberMe=true: refresh Cookie 持久化(30天);false: session cookie(关浏览器即清除) -// loginIP: 登录 IP 地址 -// 若用户处于 deleted 状态且密码正确 → 返回 ErrNeedsConfirmRestore(不自动恢复,不签发 token) func (s *AuthService) Login(req model.LoginRequest, loginIP string) (string, string, *model.User, error) { user, err := s.userRepo.FindByEmail(req.Email) + + // 维护期间:非站长一律返回统一提示(模拟 bcrypt 防时序攻击,不区分账号是否存在) + if s.siteSettings.IsMaintenanceEnabled() { + if err != nil { + _ = bcrypt.CompareHashAndPassword(dummyHash, []byte(req.Password)) + return "", "", nil, common.ErrMaintenanceMode + } + if !model.HasMinRole(user.Role, model.RoleOwner) { + _ = bcrypt.CompareHashAndPassword(dummyHash, []byte(req.Password)) + return "", "", nil, common.ErrMaintenanceMode + } + // 站长 → 继续正常登录流程 + } + if err != nil { _ = bcrypt.CompareHashAndPassword(dummyHash, []byte(req.Password)) return "", "", nil, common.ErrInvalidCred @@ -158,11 +169,6 @@ func (s *AuthService) Login(req model.LoginRequest, loginIP string) (string, str return "", "", nil, common.ErrUserBanned } - // 维护期间仅站长可登录 - if s.siteSettings.IsMaintenanceEnabled() && !model.HasMinRole(user.Role, model.RoleOwner) { - return "", "", nil, common.ErrMaintenanceMode - } - if !common.CheckPassword(req.Password, user.PasswordHash) { return "", "", nil, common.ErrInvalidCred }