Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement reCaptcha into a flutter app

I am trying to implement the reCaptcha function to my flutter app, but in the captcha registration I need to provide a domain which I don't have one for a mobile app. I have browsed several guides teaching how to implement reCaptcha into a mobile app, yet those guides registered their reCaptcha with package names but not domains. What is the correct way to implement reCaptcha in a flutter app, or any mobile app in 2020?

like image 481
bananagag Avatar asked Mar 13 '20 18:03

bananagag


People also ask

What is flutter reCAPTCHA?

Flutter Recaptcha A Flutter plugin for Google ReCaptcha powered by software Incubator. Getting Started This plugin requires Webviewto use Google ReCaptcha. This plugin only supports Google ReCAPTCHA V2(v1 & v3 not supported)

How to add CAPTCHA in flutter?

As with the plugin, use a webview to open the page, then capture the post output of the form and ip address of user submitting the form, using something like this, then send it to flutter and then submit your request with that information, and use the Google library to verify the captcha.

How to add ReCAPTCHA to your website or mobile app?

First, choose the type of reCAPTCHA and then fill in authorized domains or package names. After you have accepted the terms of service, click Register to get new API key pair. Now, perform the following steps to add reCAPTCHA to your site or mobile application: Verify the user's response.

What is the reCAPTCHA developer documentation?

Welcome to the reCAPTCHA developer documentation. reCAPTCHA protects you against spam and other types of automated abuse. Here, we explain how to add reCAPTCHA to your site or application. This documentation is designed for people familiar with HTML forms, server-side processing or mobile application development.


1 Answers

You can use this plugin, flutter_recaptcha.

For the domain, I had the same issue. I first found that I needed to use the "I'm not a robot" checkbox option from here and I had to check the github repository to find this information, "!!! Remember to add this domain into the reCaptcha setting: recaptcha-flutter-plugin.firebaseapp.com," which explains it.

I was lost for a bit after not seeing that on the main page, but now it makes sense. Hopefully it helps.

Edit

I noticed something after trying it out, that I'd like to mention. The plugin does not provide a captcha response for using to authenticate the user server-side, so it does not seem very useful as it is. However, it is a simple plugin, so it may be possible to use it as an example. The steps, I think, would be to create a webpage with the captcha. As with the plugin, use a webview to open the page, then capture the post output of the form and ip address of user submitting the form, using something like this, then send it to flutter and then submit your request with that information, and use the Google library to verify the captcha.

Instructions

I just finished implementing this and I found a good way that works. First, create an html page, like this:

<html>
  <head>
    <title>reCAPTCHA</title>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
  </head>
  <body style='background-color: aqua;'>
    <div style='height: 60px;'></div>
    <form action="?" method="POST">
      <div class="g-recaptcha" 
        data-sitekey="YOUR-SITE-KEY"
        data-callback="captchaCallback"></div>

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

Then, host that on your domain, say example.com/captcha.

Then, create a flutter Widget, like this:

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://example.com/captcha.html",
        javascriptMode: JavascriptMode.unrestricted,
        javascriptChannels: Set.from([
          JavascriptChannel(
            name: 'Captcha',
            onMessageReceived: (JavascriptMessage message) {
              //This is where you receive message from
              //javascript code and handle in Flutter/Dart
              //like here, the message is just being printed
              //in Run/LogCat window of android studio
              //print(message.message);
              widget.callback(message.message);
              Navigator.of(context).pop();
            })
        ]),
        onWebViewCreated: (WebViewController w) {
          webViewController = w;
        },
      )
    );
  }

}

Make sure you registered for a captcha key at https://www.google.com/recaptcha (click on "Admin Console" at the top-right).

Then, you have the front-end built. To call a captcha, just run:

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

You can use whatever callback you want to, like this:

class GenericState extends State<Generic>{
void methodWithCaptcha(String captchaCode){
  // Do something with captchaCode
}

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

Server-side, you can follow the instructions here (I followed the sections "Direct Download" and "Usage"). I found that for the usage, I could simply use the code:

$recaptcha = new \ReCaptcha\ReCaptcha($secret);
$resp = $recaptcha->verify($gRecaptchaResponse, $remoteIp);
if ($resp->isSuccess()) {
    // Verified!
} else {
    $errors = $resp->getErrorCodes();
}

Using setExpectedHostname, like in the example, was unnecessary.

After that, everything works! I think this is currently the best way to implement Google reCaptcha V2 in flutter (for both iOS and Android).

like image 65
JVE999 Avatar answered Oct 06 '22 01:10

JVE999