fix(auth): replace submit turnstile widget with VerifyTurnstileForRegister

Port upstream's VerifyTurnstileForRegister which skips the duplicate
Turnstile check when email verify flow is already completed, instead of
requiring a second Turnstile widget on the verify page.
This commit is contained in:
erio
2026-03-01 16:34:14 +08:00
parent 34ccfe45ea
commit 0b96c7a65e
3 changed files with 16 additions and 45 deletions

View File

@@ -113,8 +113,8 @@ func (h *AuthHandler) Register(c *gin.Context) {
return
}
// Turnstile 验证 — 始终执行,防止机器人自动化注册
if err := h.authService.VerifyTurnstile(c.Request.Context(), req.TurnstileToken, ip.GetClientIP(c)); err != nil {
// Turnstile 验证(邮箱验证码注册场景避免重复校验一次性 token
if err := h.authService.VerifyTurnstileForRegister(c.Request.Context(), req.TurnstileToken, ip.GetClientIP(c), req.VerifyCode); err != nil {
response.ErrorFrom(c, err)
return
}

View File

@@ -308,6 +308,17 @@ func (s *AuthService) SendVerifyCodeAsync(ctx context.Context, email string) (*S
}, nil
}
// VerifyTurnstileForRegister 在注册场景下验证 Turnstile。
// 当邮箱验证开启且已提交验证码时,说明验证码发送阶段已完成 Turnstile 校验,
// 此处跳过二次校验,避免一次性 token 在注册提交时重复使用导致误报失败。
func (s *AuthService) VerifyTurnstileForRegister(ctx context.Context, token, remoteIP, verifyCode string) error {
if s.IsEmailVerifyEnabled(ctx) && strings.TrimSpace(verifyCode) != "" {
logger.LegacyPrintf("service.auth", "%s", "[Auth] Email verify flow detected, skip duplicate Turnstile check on register")
return nil
}
return s.VerifyTurnstile(ctx, token, remoteIP)
}
// VerifyTurnstile 验证Turnstile token
func (s *AuthService) VerifyTurnstile(ctx context.Context, token string, remoteIP string) error {
required := s.cfg != nil && s.cfg.Server.Mode == "release" && s.cfg.Turnstile.Required