Protect your React Native application using Cloudflare Turnstile.
Vlad R
Posted on February 21, 2023
Quick overview:
Turnstile is Cloudflare’s smart CAPTCHA alternative. It can be embedded into any website without sending traffic through Cloudflare and works without showing visitors a CAPTCHA.
Turnstile has a great documentation. Here is the link.
Here is how it looks like:
How it works:
Turnstile is a front-end widget that creates a token which is cryptographically secured. However, the customer cannot check the validity of the token on their end. To ensure that a token is not forged by an attacker or has not been consumed yet, the customer needs to check the validity of a token using Cloudflare’s siteverify API. A Turnstile token is valid for 300 seconds. It refreshes automatically.
Widget types:
There are three types of Turnstile widget:
- A non-intrusive interactive challenge (such as clicking a button), if the visitor is a suspected bot.
- A non-interactive challenge.
- An invisible challenge to the browser.
Pricing:
Turnstile is currently in open beta and available as a free tool, but there are still some limitations.
React Native integration:
Turnstile doesn’t offer an easy and official way to embed Turnstile into a React Native application. The only one way to render the widget in RN app is by using WebView component.
We also gonna use the invisible type of widget(set widget type in the CF dashboard). Which means our users won’t see any widget at all and we won’t have to try to style an iframe inside of an iframe in order to fit the widget into our design.
const Turnstile = () => {
const dispatch = useDispatch();
const handleMessage = (event) => {
// Now we can add this token to any request header.
// Where backend will verify the token using Cloudflare API.
const token = event.nativeEvent.data;
dispatch(setTurnstileToken(token));
};
return (
<View>
<WebView
originWhitelist={['*']}
onMessage={handleMessage}
source={{
baseUrl: '{your base url}',
html: `
<!DOCTYPE html>
<html>
<head>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=_turnstileCb" async defer></script>
</head>
<body>
<div id="myWidget"></div>
<script>
// This function is called when the Turnstile script is loaded and ready to be used.
// The function name matches the "onload=..." parameter.
function _turnstileCb() {
turnstile.render('#myWidget', {
sitekey: '{your siteKey}',
callback: (token) => {
// Success callback, which sets the token into a separate store slice.
window.ReactNativeWebView.postMessage(token);
},
});
}
</script>
</body>
</html>
`,
}}
/>
</View>
);
};
Don’t forget to change baseUrl
and siteKey
props.
Then import the component above to the App component.
const App = () => {
return (
...
<Turnstile />
)
}
That’s about it. Easy. Hope sometimes soon we’ll be able to use other types of the widget.
Photo by José Ramos
Posted on February 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.