Implementing hCaptcha in your Flutter App

You can get up and running in just a few minutes with Flutter and hCaptcha.

Below is a quick tutorial.

  1. Create a static HTML page on your server that contains your hCaptcha sitekey.
<html>
<head>
<title>hCaptcha</title>
<script src="https://hcaptcha.com/1/api.js" async defer></script>
</head>
<body style='background-color: aqua;'>
<div style='height: 60px;'></div>
<form action="?" method="POST">
<div class="h-captcha"
data-sitekey="YOUR-SITEKEY-FROM-hCaptcha-DASH"
data-callback="captchaCallback"></div>

</form>
<script>
function captchaCallback(response) {
if (typeof Captcha!=="undefined") {
Captcha.postMessage(response);
}
}
</script>
</body>
</html>

2. Create a flutter Widget:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class Captcha extends StatefulWidget {
Function callback;
Captcha(this.callback);
@override
State<StatefulWidget> createState() {
return CaptchaState();
}
}
class CaptchaState extends State<Captcha> {
WebViewController webViewController;
@override
initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Center(
child: WebView(
initialUrl: "https://YOUR-DOMAIN.com/fluttercaptcha.html",
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: Set.from([
JavascriptChannel(
name: 'Captcha',
onMessageReceived: (JavascriptMessage message) {
// message contains the 'h-captcha-response' token.
// Send it to your server in the login or other
// data for verification via /siteverify
// see: https://docs.hcaptcha.com/#server
// print(message.message);
widget.callback(message.message);
Navigator.of(context).pop();
})
]),
onWebViewCreated: (WebViewController w) {
webViewController = w;
},
));
}
}

3. And you’re pretty much done! To trigger the captcha, e.g. when a user presses “Sign up” in your app, just call it as follows:

Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return Captcha((String code)=>print("Code returned: "+code));
}
),
);

Use whatever callback you prefer, e.g. like this:

class GenericState extends State<Generic> {
void methodWithCaptcha(String captchaCode) {
// Do something with captchaCode, i.e. send to your
// server for validation by siteverify endpoint.
}
}

@override
Widget build(BuildContext context) {
return Center(
child: FlatButton(
child: Text("Click here!"),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
return Captcha(methodWithCaptcha);
}),
);
}));
}

To verify the passcode you just got from hCaptcha, you’ll just need to call siteverify on your server, as described here:
https://docs.hcaptcha.com/#server

And that’s it!

Feel free to reach out to us with any questions.

inspiration: JVE999 on StackOverflow