修复:调整游客取号限流策略
问题:移动网络共享出口 IP 会造成游客取号被误限流。 实现:移除公开取号 IP 限制,改用项目总量与手机号 HMAC 限流,并支持 Retry-After 倒计时。
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@@ -154,6 +155,43 @@ func TestPublicCreateTicketIgnoresDuplicateFromEndedSession(t *testing.T) {
|
||||
if afterCallRecorder.Code != http.StatusCreated {
|
||||
t.Fatalf("after-call status = %d, want 201; body = %s", afterCallRecorder.Code, afterCallRecorder.Body.String())
|
||||
}
|
||||
|
||||
server.publicTicketProjectLimiter = newQueryLimiter(server.now, 10, time.Minute)
|
||||
server.publicTicketPhoneLimiter = newQueryLimiter(server.now, 1, time.Minute)
|
||||
var replayBody, replayKey string
|
||||
for index := 0; index < 6; index++ {
|
||||
body := fmt.Sprintf(`{"phone":"1390000%04d","party_size":1}`, index)
|
||||
key := "same-mobile-ip-" + uuid.NewString()
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodPost, "/api/public/projects/"+projectID+"/tickets", strings.NewReader(body))
|
||||
request.RemoteAddr = "198.51.100.27:42000"
|
||||
request.Header.Set("Idempotency-Key", key)
|
||||
server.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusCreated {
|
||||
t.Fatalf("same-IP distinct phone %d status = %d, want 201; body = %s", index, recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if index == 0 {
|
||||
replayBody, replayKey = body, key
|
||||
}
|
||||
}
|
||||
|
||||
replayRecorder := httptest.NewRecorder()
|
||||
replayRequest := httptest.NewRequest(http.MethodPost, "/api/public/projects/"+projectID+"/tickets", strings.NewReader(replayBody))
|
||||
replayRequest.RemoteAddr = "198.51.100.27:42000"
|
||||
replayRequest.Header.Set("Idempotency-Key", replayKey)
|
||||
server.Handler().ServeHTTP(replayRecorder, replayRequest)
|
||||
if replayRecorder.Code != http.StatusCreated {
|
||||
t.Fatalf("idempotent replay status = %d, want 201; body = %s", replayRecorder.Code, replayRecorder.Body.String())
|
||||
}
|
||||
|
||||
limitedRecorder := httptest.NewRecorder()
|
||||
limitedRequest := httptest.NewRequest(http.MethodPost, "/api/public/projects/"+projectID+"/tickets", strings.NewReader(replayBody))
|
||||
limitedRequest.RemoteAddr = "203.0.113.44:42000"
|
||||
limitedRequest.Header.Set("Idempotency-Key", "new-intent-"+uuid.NewString())
|
||||
server.Handler().ServeHTTP(limitedRecorder, limitedRequest)
|
||||
if limitedRecorder.Code != http.StatusTooManyRequests {
|
||||
t.Fatalf("same project/phone new intent status = %d, want 429; body = %s", limitedRecorder.Code, limitedRecorder.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestInternalPhoneLookupUsesLatestActiveSessionPerProject(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user