Was used in notlink — a blazingly fast url shortener ever built with rust programming language. Check: https://notl.ink
The “Invalid token” error occurs because the Turnstile token is being reused for multiple submissions. Cloudflare Turnstile tokens are single-use; once validated, they can’t be used again. Here’s how to fix it:
- Reset the Turnstile widget after each submission
 
Update your frontend code to reset the Turnstile widget and clear the token state after submission:
// Add a ref to the Turnstile component
const turnstileRef = useRef();
async function handleShorten(val: string) {
  // ... existing code ...
try {
    const response = await fetch(/api/shorten, { /* ... */ });
    const data: ShortURLResponse = await response.json();
// Reset Turnstile after successful submission
turnstileRef.current?.reset();
setTurnstileToken("");
setTurnstileStatus("required");
} catch (error) {
    console.error('Error:', error);
  } finally {
    setLoading(false);
    // Ensure Turnstile is reset even if there's an error
    turnstileRef.current?.reset();
    setTurnstileToken("");
    setTurnstileStatus("required");
  }
}
// Update your Turnstile component with the ref
  ref={turnstileRef}
  siteKey={process.env.TURNSTILE_SITE_KEY!}
  // ... other props ...
/>
- (Optional) Clear token state on expiration/error
 
Enhance your Turnstile event handlers:
  // ... other props ...
  onExpire={() => {
    setTurnstileStatus("expired");
    setTurnstileError("Security check expired. Please verify again.");
    setTurnstileToken(""); // Clear expired token
  }}
  onError={() => {
    setTurnstileStatus("error");
    setTurnstileError("Security check failed. Please try again.");
    setTurnstileToken(""); // Clear invalid token
  }}
/>
Why this works:
Each submission now requires a fresh Turnstile verification
The token state is cleared after submission/errors/expiration
The Turnstile widget is reset to force a new challenge
Additional recommendations for your backend:
Ensure your idempotencyKey implementation matches Turnstile's requirements
Consider adding rate limiting to prevent abuse
Verify the token expiration time (typically 5 minutes)
By implementing these changes, users will need to complete a new Turnstile verification for each submission, preventing token reuse and the “Invalid token” error.
    
Top comments (0)