Turnstile CAPTCHA
Javascript
Head over to the official Turnstile documentation to read more about how to integrate Cloudflare's CAPTCHA solution.
Insert the Turnstile script snippet in your HTML’s <head> element:
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
Configuration
Within your Cloudflare account under Turnstile create a new Site and get the site key and site secret. Set both in your .env file.
TURNSTILE_SITE_KEY=sitekey
TURNSTILE_SECRET_KEY=sitesecret
Alternatively you could use thebnomei.kart.turnstile.sitekeyandbnomei.kart.turnstile.secretkeyconfig options. But using the.envfile is safer.
Widget
Render the Turnstile widget with the code from the documentation or use the following snippet kart/turnstile-widget.
<?php snippet('kart/turnstile-widget') ?>
Securing Forms
It might suffice to only secure routes accessible before the user is logged in, like the Login- and Register/Sign-Up-Forms. That is assuming bots do not create valid logins.
Use the code from the documentation or the following snippet kart/turnstile-form.
<form action="<?= kart()->urls()->magiclink() ?>" method="POST">
<label>
<input type="email" name="email" required
placeholder="<?= t('email') ?>" autocomplete="email"
value="<?= urldecode(get('email', '')) ?>">
</label>
<?php snippet('kart/turnstile-form') ?>
<input type="hidden" name="redirect" value="<?= url('kart/login') ?>?status=sent">
<input type="hidden" name="success_url" value="<?= url('kart') ?>?msg=Welcome%20back">
<button type="submit"><?= t('login') ?> <?= t('link') ?></button>
</form>
Behind the Scenes
The endpoints intended for public use, which are most likely targeted by bots (login, register/signup, magic-link), are preconfigured with a check for the Turnstile token.
If posted with the form the \Bnomei\Kart\Router::denied()-helper will query the https://challenges.cloudflare.com/turnstile/v0/siteverify endpoint with your secretkey and check if the form request is legit or not.
On success, the form will continue as intended. If not, it will redirect to the error page or yield a 401 HTTP status code.