修复:调整游客取号限流策略

问题:移动网络共享出口 IP 会造成游客取号被误限流。

实现:移除公开取号 IP 限制,改用项目总量与手机号 HMAC 限流,并支持 Retry-After 倒计时。
This commit is contained in:
2026-07-31 22:56:33 +08:00
parent 3f4a9bf398
commit c2a5281534
17 changed files with 357 additions and 73 deletions

View File

@@ -24,18 +24,21 @@ type queryLimitEntry struct {
count int
}
// queryLimiter is deliberately small and in-memory for the temporary public
// phone lookup. The production replacement will be an OTP or external
// identity provider, so this limiter is only a safety net for the test flow.
// queryLimiter is a per-process fixed-window safety limit. Expired entries are
// removed opportunistically so unique keys do not accumulate indefinitely.
type queryLimiter struct {
mu sync.Mutex
entries map[string]queryLimitEntry
now func() time.Time
limit int
window time.Duration
mu sync.Mutex
entries map[string]queryLimitEntry
now func() time.Time
limit int
window time.Duration
nextCleanup time.Time
}
func newQueryLimiter(now func() time.Time, limit int, window time.Duration) *queryLimiter {
if limit <= 0 || window <= 0 {
return nil
}
return &queryLimiter{
entries: make(map[string]queryLimitEntry), now: now, limit: limit, window: window,
}
@@ -49,6 +52,14 @@ func (l *queryLimiter) allow(key string) (bool, time.Duration) {
defer l.mu.Unlock()
now := l.now()
if l.nextCleanup.IsZero() || !now.Before(l.nextCleanup) {
for entryKey, existing := range l.entries {
if now.Sub(existing.windowStart) >= l.window {
delete(l.entries, entryKey)
}
}
l.nextCleanup = now.Add(l.window)
}
entry, ok := l.entries[key]
if !ok || now.Sub(entry.windowStart) >= l.window {
entry = queryLimitEntry{windowStart: now}