[GH-ISSUE #115] 增加Cloudflare Turnstile 验证码支持 #85

Closed
opened 2026-03-04 12:18:49 +03:00 by kerem · 2 comments
Owner

Originally created by @gitiy1 on GitHub (Nov 5, 2022).
Original GitHub issue: https://github.com/ADD-SP/ngx_waf/issues/115

Turnstile是cloudflare新推出的验证码服务, 无需视觉拼图即可确认访问者为真实人类,为网站访问者提供更好的体验
Website: https://www.cloudflare.com/zh-cn/products/turnstile/

Originally created by @gitiy1 on GitHub (Nov 5, 2022). Original GitHub issue: https://github.com/ADD-SP/ngx_waf/issues/115 Turnstile是cloudflare新推出的验证码服务, 无需视觉拼图即可确认访问者为真实人类,为网站访问者提供更好的体验 Website: https://www.cloudflare.com/zh-cn/products/turnstile/
kerem closed this issue 2026-03-04 12:18:50 +03:00
Author
Owner

@hibobmaster commented on GitHub (Nov 5, 2022):

其实目前是可以使用cloudflare turnstile的,prov使用reCAPTCHAv2/reCAPTCHAv3
https://docs.addesp.com/ngx_waf/advance/directive.html#waf-captcha
把里面的 api 填写为 https://challenges.cloudflare.com/turnstile/v0/siteverify
再把html模板里的脚本改为cf提供的配置即可,我测试下面的配置是okay的
参考: https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha/
captcha-v2-turnstile.html

<!DOCTYPE html>
<html lang="en">
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Please complete the captcha</title>
  <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
  <style type="text/css">
    div {
      text-align: left;
    }
  </style>
  <script>
    function onSubmit(token) {
      let reqBody = "g-recaptcha-response=" + token;
      let httpRequest = new XMLHttpRequest();
      httpRequest.open("POST", "/captcha");
      httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      httpRequest.send(reqBody);
      httpRequest.onreadystatechange = () => {
        if (httpRequest.readyState == 4 && httpRequest.status == 200) {
          let text = httpRequest.responseText;
          switch (text) {
            case "good":
              window.location.reload();
              break;
            case "bad":
              alert("Bad CAPTCHA, please refresh the page and try again.\n"
                  + "您未能通过人机验证,请刷新页面后重试。");
              break;
            default:
              alert("Unexpected error occurred, please refresh the page and try again.\n"
                  + "发生了意料之外的错误,请刷新页面后重试。");
          }
        }
      }
    }
  </script>
</head>

<body>
  <h1>Please complete the captcha.</h1>
  <h1>请完成验证码</h1>
  <div class="cf-turnstile" data-sitekey="xxxxxxxxxxxxxxxxxx" data-callback='onSubmit'></div>
  </div>
</body>

</html>

captcha-v3-turnstile.html

<!DOCTYPE html>
<html lang="en">
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Please complete the captcha</title>
  <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?compat=recaptcha" async defer></script>
  <style type="text/css">
    div {
      text-align: center;
    }
  </style>
  <script>
    function onSubmit(token) {
      let reqBody = "g-recaptcha-response=" + token;
      let httpRequest = new XMLHttpRequest();
      httpRequest.open("POST", "/captcha");
      httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      httpRequest.send(reqBody);
      httpRequest.onreadystatechange = () => {
        if (httpRequest.readyState == 4 && httpRequest.status == 200) {
          let text = httpRequest.responseText;
          switch (text) {
            case "good":
              window.location.reload();
              break;
            case "bad":
              alert("Bad CAPTCHA, please refresh the page and try again.\n"
                  + "您未能通过人机验证,请刷新页面后重试。");
              break;
            default:
              alert("Unexpected error occurred, please refresh the page and try again.\n"
                  + "发生了意料之外的错误,请刷新页面后重试。");
          }
        }
      }
    }
  </script>
</head>

<body>
  <h1>Please complete the captcha.</h1>
  <h1>请完成验证码</h1>
  <div>
    <button class="g-recaptcha" data-sitekey="xxxxxxxxxxx"
    data-callback='onSubmit' style="font-size:25px" data-action='submit'>CLICK ME (点击此处)</button>
  </div>
</body>

</html>
<!-- gh-comment-id:1304555848 --> @hibobmaster commented on GitHub (Nov 5, 2022): 其实目前是可以使用cloudflare turnstile的,`prov`使用`reCAPTCHAv2/reCAPTCHAv3` https://docs.addesp.com/ngx_waf/advance/directive.html#waf-captcha 把里面的 api 填写为 https://challenges.cloudflare.com/turnstile/v0/siteverify 再把html模板里的脚本改为cf提供的配置即可,我测试下面的配置是okay的 参考: https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha/ **captcha-v2-turnstile.html** ```html <!DOCTYPE html> <html lang="en"> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Please complete the captcha</title> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <style type="text/css"> div { text-align: left; } </style> <script> function onSubmit(token) { let reqBody = "g-recaptcha-response=" + token; let httpRequest = new XMLHttpRequest(); httpRequest.open("POST", "/captcha"); httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); httpRequest.send(reqBody); httpRequest.onreadystatechange = () => { if (httpRequest.readyState == 4 && httpRequest.status == 200) { let text = httpRequest.responseText; switch (text) { case "good": window.location.reload(); break; case "bad": alert("Bad CAPTCHA, please refresh the page and try again.\n" + "您未能通过人机验证,请刷新页面后重试。"); break; default: alert("Unexpected error occurred, please refresh the page and try again.\n" + "发生了意料之外的错误,请刷新页面后重试。"); } } } } </script> </head> <body> <h1>Please complete the captcha.</h1> <h1>请完成验证码</h1> <div class="cf-turnstile" data-sitekey="xxxxxxxxxxxxxxxxxx" data-callback='onSubmit'></div> </div> </body> </html> ``` **captcha-v3-turnstile.html** ```html <!DOCTYPE html> <html lang="en"> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Please complete the captcha</title> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?compat=recaptcha" async defer></script> <style type="text/css"> div { text-align: center; } </style> <script> function onSubmit(token) { let reqBody = "g-recaptcha-response=" + token; let httpRequest = new XMLHttpRequest(); httpRequest.open("POST", "/captcha"); httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); httpRequest.send(reqBody); httpRequest.onreadystatechange = () => { if (httpRequest.readyState == 4 && httpRequest.status == 200) { let text = httpRequest.responseText; switch (text) { case "good": window.location.reload(); break; case "bad": alert("Bad CAPTCHA, please refresh the page and try again.\n" + "您未能通过人机验证,请刷新页面后重试。"); break; default: alert("Unexpected error occurred, please refresh the page and try again.\n" + "发生了意料之外的错误,请刷新页面后重试。"); } } } } </script> </head> <body> <h1>Please complete the captcha.</h1> <h1>请完成验证码</h1> <div> <button class="g-recaptcha" data-sitekey="xxxxxxxxxxx" data-callback='onSubmit' style="font-size:25px" data-action='submit'>CLICK ME (点击此处)</button> </div> </body> </html> ```
Author
Owner

@gitiy1 commented on GitHub (Nov 11, 2022):

十分感谢!希望项目越做越好!

<!-- gh-comment-id:1311410922 --> @gitiy1 commented on GitHub (Nov 11, 2022): 十分感谢!希望项目越做越好!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ngx_waf#85
No description provided.