From 13bab28926a4e857890c7a6367ce1928bbdf039d Mon Sep 17 00:00:00 2001 From: lan Date: Tue, 2 Dec 2025 10:38:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E5=92=8C=E9=AA=8C=E8=AF=81=E7=A0=81=E9=AA=8C=E8=AF=81=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E6=AC=A1=E6=95=B0=E9=99=90=E5=88=B6=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E8=B4=A6=E5=8F=B7=E9=94=81=E5=AE=9A=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/user_service.go | 10 ++++++++++ internal/service/verification_service.go | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/internal/service/user_service.go b/internal/service/user_service.go index 6c46643..4a98ca7 100644 --- a/internal/service/user_service.go +++ b/internal/service/user_service.go @@ -109,6 +109,11 @@ func LoginUserWithRateLimit(redisClient *redis.Client, jwtService *auth.JWTServi if redisClient != nil { identifier := usernameOrEmail + ":" + ipAddress count, _ := RecordLoginFailure(ctx, redisClient, identifier) + // 检查是否触发锁定 + if count >= MaxLoginAttempts { + logFailedLogin(0, ipAddress, userAgent, "用户不存在-账号已锁定") + return nil, "", fmt.Errorf("登录失败次数过多,账号已被锁定 %d 分钟", int(LoginLockDuration.Minutes())) + } remaining := MaxLoginAttempts - count if remaining > 0 { logFailedLogin(0, ipAddress, userAgent, "用户不存在") @@ -131,6 +136,11 @@ func LoginUserWithRateLimit(redisClient *redis.Client, jwtService *auth.JWTServi if redisClient != nil { identifier := usernameOrEmail + ":" + ipAddress count, _ := RecordLoginFailure(ctx, redisClient, identifier) + // 检查是否触发锁定 + if count >= MaxLoginAttempts { + logFailedLogin(user.ID, ipAddress, userAgent, "密码错误-账号已锁定") + return nil, "", fmt.Errorf("登录失败次数过多,账号已被锁定 %d 分钟", int(LoginLockDuration.Minutes())) + } remaining := MaxLoginAttempts - count if remaining > 0 { logFailedLogin(user.ID, ipAddress, userAgent, "密码错误") diff --git a/internal/service/verification_service.go b/internal/service/verification_service.go index 2001be7..41ac541 100644 --- a/internal/service/verification_service.go +++ b/internal/service/verification_service.go @@ -102,15 +102,25 @@ func VerifyCode(ctx context.Context, redisClient *redis.Client, email, code, cod // 从Redis获取验证码 storedCode, err := redisClient.Get(ctx, codeKey) if err != nil { - // 记录失败尝试 - RecordVerifyFailure(ctx, redisClient, email, codeType) + // 记录失败尝试并检查是否触发锁定 + count, _ := RecordVerifyFailure(ctx, redisClient, email, codeType) + if count >= MaxVerifyAttempts { + return fmt.Errorf("验证码错误次数过多,账号已被锁定 %d 分钟", int(VerifyLockDuration.Minutes())) + } + remaining := MaxVerifyAttempts - count + if remaining > 0 { + return fmt.Errorf("验证码已过期或不存在,还剩 %d 次尝试机会", remaining) + } return fmt.Errorf("验证码已过期或不存在") } // 验证验证码 if storedCode != code { - // 记录失败尝试 + // 记录失败尝试并检查是否触发锁定 count, _ := RecordVerifyFailure(ctx, redisClient, email, codeType) + if count >= MaxVerifyAttempts { + return fmt.Errorf("验证码错误次数过多,账号已被锁定 %d 分钟", int(VerifyLockDuration.Minutes())) + } remaining := MaxVerifyAttempts - count if remaining > 0 { return fmt.Errorf("验证码错误,还剩 %d 次尝试机会", remaining)