Αντικατάσταση Google CAPTCHA με cloudflare turnstile

  1. Σύνδεση στο https://dash.cloudflare.com/
  2. Μπαίνουμε στο application security > turnstile
  3. Κάνουμε click add widget
  4. Προσθέτουμε hostnames
  5. Αποθηκεύουμε το widget και κρατάμε το public/private key που μας δινει γιατι θα τα χρησιμοποιήσουμε αργότερα
  6. <body>
        <div id="captcha" data-size="invisible"></div>
    
        <button id="send">Send</button>
    
        <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstile&render=explicit" async defer></script>
    
        <script>
            let widgetId;
    
            // Cloudflare Turnstile (global callback referenced by the API script URL)
            window.turnstileWidgetId = null;
            window.turnstileToken = "";
            window.turnstileAutoSubmit = false;
      
            window.setSignInDisabled = function (disabled) {
              const btn = document.getElementById("sign-in");
              btn.disabled = !!disabled;
              btn.style.opacity = disabled ? "0.7" : "1";
              btn.style.cursor = disabled ? "not-allowed" : "pointer";
            };
      
            window.onloadTurnstile = function () {
              const render = () => {
                const el = document.getElementById("cf-turnstile");
    
                window.turnstileWidgetId = turnstile.render(el, {
                  sitekey: "PUBLIC_KEY",
                  // If you want to use ONLY your own "Είσοδος" button, keep this invisible.
                  size: "invisible",
                  callback: function (token) {
                    window.turnstileToken = token || "";
                    window.setSignInDisabled(false);
                    window.turnstileAutoSubmit = false;
                    document.getElementById("sign-in")?.click();
                  },
                  "expired-callback": function () {
                    window.turnstileToken = "";
                    window.turnstileAutoSubmit = false;
                    window.setSignInDisabled(false);
                  },
                  "error-callback": function () {
                    window.turnstileToken = "";
                    window.turnstileAutoSubmit = false;
                    window.setSignInDisabled(false);
                  },
                });
              };
      
              if (document.readyState === "loading") {
                document.addEventListener("DOMContentLoaded", render);
              } else {
                render();
              }
            };
    
            document.getElementById("send").addEventListener("click", () => {
                event.preventDefault();
    
                let fields = {
                  $email: document.getElementById("email"),
                  $password: document.getElementById("password"),
                };
          
                const turnstileToken =
                  window.turnstileToken ||
                  (window.turnstileWidgetId !== null && typeof turnstile !== "undefined"
                    ? turnstile.getResponse(window.turnstileWidgetId)
                    : "");
          
                if (!turnstileToken) {
                  // Disable your login button while captcha runs
                  window.setSignInDisabled(true);
                  window.turnstileAutoSubmit = true;
          
                  // For invisible Turnstile, execute it now
                  try {
                    turnstile.execute(window.turnstileWidgetId);
                  } catch (e) {
                    window.setSignInDisabled(false);
                    window.turnstileAutoSubmit = false;
                  }
                  return;
                }
          
                // Disable while the login request is in-flight (prevents double submit)
                window.setSignInDisabled(true);
      
                postData("/api.php?op=signIn", {
                  email: fields.$email.value,
                  password: fields.$password.value,
                  turnstileToken: turnstileToken,
                  "cf-turnstile-response": turnstileToken,
                })
            });
        </script>
    </body>
  7. Βάζουμε στο script πάνω και όταν κάνουμε send έχουμε πλέον το token που θα σταλθεί στο backend
  8. Στο backend μετά κάνουμε το παρακάτω για επιβεβαίωση οτι έιναι οκ να προχωρήσουμε
  9. $token = $_POST['cf-turnstile-response'];   // <-- Token from Turnstile
    $secret = "YOUR_SECRET_KEY";
    
    $verify = curl_init("https://challenges.cloudflare.com/turnstile/v0/siteverify");
    curl_setopt($verify, CURLOPT_POST, true);
    curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($verify, CURLOPT_POSTFIELDS, [
        'secret' => $secret,
        'response' => $token
    ]);
    
    $response = json_decode(curl_exec($verify), true);
    
    if ($response["success"]) {
        echo "HUMAN VERIFIED!";
    } else {
        echo "FAILED";
    }

Μερικές επιπλέον επεξηγήσεις για το παραπάνω. Κάνουμε οπω ειναι copy paste αυτο το κομματι

let widgetId;

        // Cloudflare Turnstile (global callback referenced by the API script URL)
        window.turnstileWidgetId = null;
        window.turnstileToken = "";
        window.turnstileAutoSubmit = false;
  
        window.setSignInDisabled = function (disabled) {
          const btn = document.getElementById("sign-in");
          btn.disabled = !!disabled;
          btn.style.opacity = disabled ? "0.7" : "1";
          btn.style.cursor = disabled ? "not-allowed" : "pointer";
        };
  
        window.onloadTurnstile = function () {
          const render = () => {
            const el = document.getElementById("cf-turnstile");

            window.turnstileWidgetId = turnstile.render(el, {
              sitekey: "PUBLIC_KEY",
              // If you want to use ONLY your own "Είσοδος" button, keep this invisible.
              size: "invisible",
              callback: function (token) {
                window.turnstileToken = token || "";
                window.setSignInDisabled(false);
                window.turnstileAutoSubmit = false;
                document.getElementById("sign-in")?.click();
              },
              "expired-callback": function () {
                window.turnstileToken = "";
                window.turnstileAutoSubmit = false;
                window.setSignInDisabled(false);
              },
              "error-callback": function () {
                window.turnstileToken = "";
                window.turnstileAutoSubmit = false;
                window.setSignInDisabled(false);
              },
            });
          };
  
          if (document.readyState === "loading") {
            document.addEventListener("DOMContentLoaded", render);
          } else {
            render();
          }
        };

Δε θα χρειαστει να αλλαξουμε κατι εδω εκτος απο το document.getElementById("sign-in") να δειχνει το κουμπι συνδεσης. και έπειτα παίρνουμε οπως ειναι αυτο το κομματι πριν το request συνδεσης:

const turnstileToken =
  window.turnstileToken ||
  (window.turnstileWidgetId !== null && typeof turnstile !== "undefined"
    ? turnstile.getResponse(window.turnstileWidgetId)
    : "");

if (!turnstileToken) {
  // Disable your login button while captcha runs
  window.setSignInDisabled(true);
  window.turnstileAutoSubmit = true;

  // For invisible Turnstile, execute it now
  try {
    turnstile.execute(window.turnstileWidgetId);
  } catch (e) {
    window.setSignInDisabled(false);
    window.turnstileAutoSubmit = false;
  }
  return;
}

// Disable while the login request is in-flight (prevents double submit)
window.setSignInDisabled(true);

Και απλα συμπεριλαμβανουμε στην αποστολη μετα το 

turnstileToken

Revision #4
Created 2025-12-12 13:54:20 UTC by Admin
Updated 2025-12-12 14:49:51 UTC by Admin