41
General / Re: Cloudflare Turnstile Non-interactive challenge
« Last post by xmanhattan on October 01, 2025, 12:50:20 »Ouch! My fault, I forgot a semi-colon. 
I will blame it on old age!
Thank you for reminding me about the error log.
By the way, here is the code in case anyone wants to see it.

I will blame it on old age!
Thank you for reminding me about the error log.
By the way, here is the code in case anyone wants to see it.
Code: [Select]
<?php
/*
Cloudflare Turnstile Captcha Non-Interactive Challenge
Client-side Integration
https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/
Server-Side Integration
https://developers.cloudflare.com/turnstile/get-started/server-side-validation/
Cloudflare offer 3 types of cloudflare turnstile captcha
Managed challenge
Non-interactive challenge
Invisible challenge
Mandatory server-side validation
You must call Siteverify API to complete your Turnstile configuration.
The client-side widget alone does not provide protection.
You must validate tokens on your server because tokens can be forged by attackers,
expire after 5 minutes (300 seconds), and are single-use and cannot be validated twice.
Client-side verification alone leaves major security vulnerabilities.
*/
// Cloudflare Turnstile widget Client-side Integration
//Turnstile widget
//$SiteKey = "YOUR-SITE-KEY";
?>
<div class="cf-turnstile" data-sitekey="<?php echo $SiteKey; ?>" data-theme="light"></div>
<!-- end Cloudflare Turnstile widget Client-side Integration -->
<?php
// ----------------------------------------------------------------------
// Server-Side Integration
// ----------------------------------------------------------------------
function validateTurnstile($token, $secret, $remoteip = null) {
$url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
$data = [
'secret' => $secret,
'response' => $token
];
if ($remoteip) {
$data['remoteip'] = $remoteip;
}
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
if ($response === FALSE) {
return ['success' => false, 'error-codes' => ['internal-error']];
}
return json_decode($response, true);
}
// Usage
$secret_key = 'your-secret-key';
$token = $_POST['cf-turnstile-response'] ?? '';
$remoteip = $\_SERVER['HTTP_CF_CONNECTING_IP'] ??
$\_SERVER['HTTP_X_FORWARDED_FOR'] ??
$\_SERVER['REMOTE_ADDR'];
$validation = validateTurnstile($token, $secret_key, $remoteip);
if ($validation['success']) {
// Valid token - process form
echo "Form submission successful!";
// Process your form data here
} else {
// Invalid token - show error
echo "Verification failed. Please try again.";
error_log('Turnstile validation failed: ' . implode(', ', $validation['error-codes']));
}
?>

Recent Posts