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

问题:移动网络共享出口 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

@@ -60,12 +60,6 @@ func (s *Server) publicCreateTicket(w http.ResponseWriter, r *http.Request) {
writeError(w, err)
return
}
if s.publicTicketLimiter != nil {
if allowed, retry := s.publicTicketLimiter.allow("ip:" + publicQueryClientKey(r)); !allowed {
writePublicTicketRateLimit(w, retry)
return
}
}
var actor model.User
if err := s.db.WithContext(r.Context()).Where("username = ?", model.PublicVisitorUsername).First(&actor).Error; err != nil {
writeError(w, err)
@@ -74,6 +68,21 @@ func (s *Server) publicCreateTicket(w http.ResponseWriter, r *http.Request) {
s.createTicketForActor(w, r, actor.ID, true)
}
func publicTicketProjectLimitKey(projectID string) string {
return "project:" + projectID
}
func publicTicketPhoneLimitKey(projectID, phoneDigest string) string {
return "project:" + projectID + ":phone:" + phoneDigest
}
func (s *Server) allowPublicTicket(projectID, phoneDigest string) (bool, time.Duration) {
if allowed, retry := s.publicTicketProjectLimiter.allow(publicTicketProjectLimitKey(projectID)); !allowed {
return false, retry
}
return s.publicTicketPhoneLimiter.allow(publicTicketPhoneLimitKey(projectID, phoneDigest))
}
type publicPhoneQueryRequest struct {
Phone string `json:"phone"`
}