Repository navigation
fix(email): 验证码尝试次数原子化 + 重置密码 token 哈希存储且原子单次消费 - #7676
Merged
Wei-Shaw merged 1 commit intoOct 2, 2026
Merged
Conversation
…okens - Verification code attempts (register + notify email) are now reserved via an atomic Redis INCR (Lua) before comparing, so concurrent wrong guesses cannot exceed the 5-attempt cap. - Password reset tokens are stored as SHA-256 hashes and consumed with an atomic Lua compare-and-delete, so a token can only be used once even under concurrent requests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 28, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
改动
EmailCache新增IncrVerificationCodeAttempts/IncrNotifyVerifyCodeAttempts:Redis 实现用 Lua 脚本(EXISTS + INCR + 按验证码剩余 PTTL 设置过期),计数存于独立 key<code key>:attempts;设置新验证码时同时清零计数,删除时一并删除。verifyCodeWithAttempts。sha256(token)的 hex;VerifyPasswordResetToken对哈希做subtle.ConstantTimeCompare;新增ConsumePasswordResetToken(Lua 比较哈希后 DEL,原子),只有一个并发请求能成功。错误 token 不会删除有效 token。兼容性
测试
internal/repository/email_cache_atomic_test.go(miniredis,-race):internal/service/email_service_reset_token_test.go(unit):消费时传给 cache 的是 SHA-256 哈希;旧明文存储值不再通过校验。go build ./...、go vet ./internal/...、go vet -tags unit ./internal/...、go test -tags unit ./internal/service/ ./internal/handler/ ./internal/repository/全部通过。🤖 Generated with Claude Code