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)