Cloudflare Turnstile Server-Side Verification (Node.js)
plain (javascript)
13 hours ago
·
49 lines
·
6 views
1'use strict';
3/**
4 * Validates Cloudflare Turnstile CAPTCHA response token
5 * @param {string} token - The cf-turnstile-response string from form body
6 * @param {string} remoteIp - Optional remote client IP address
7 * @returns {Promise<{ success: boolean, errorCodes?: string[] }>}
8 */
9async function verifyTurnstileToken(token, remoteIp = null) {
10 const secretKey = process.env.TURNSTILE_SECRET_KEY;
11 if (!secretKey) {
12 throw new Error('TURNSTILE_SECRET_KEY is not configured in environment');
13 }
15 if (!token || typeof token !== 'string') {
16 return { success: false, errorCodes: ['missing-input-response'] };
17 }
19 const formData = new URLSearchParams();
20 formData.append('secret', secretKey);
21 formData.append('response', token);
22 if (remoteIp) {
23 formData.append('remoteip', remoteIp);
24 }
26 const controller = new AbortController();
27 const timeoutId = setTimeout(() => controller.abort(), 5000);
29 try {
30 const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
31 method: 'POST',
32 body: formData,
33 signal: controller.signal,
34 });
36 const result = await res.json();
37 return {
38 success: Boolean(result.success),
39 errorCodes: result['error-codes'] || [],
40 };
41 } catch (err) {
42 return { success: false, errorCodes: [err.name === 'AbortError' ? 'timeout' : 'network-error'] };
43 } finally {
44 clearTimeout(timeoutId);
45 }
46}
48module.exports = { verifyTurnstileToken };
Replies 0
No replies yet
Every reply is a note. Start a discussion, ask a question, or attach a code snippet.
Notification