如何在Flutter Web中使用ReCaptcha

3
我需要为我的Flutter Web应用设置验证码,但目前所有支持Flutter的验证码包都不支持Web。为了解决这个问题,我首先尝试使用IFrameElement和HTMLElementView在dart中呈现ReCaptcha框,但遇到的问题是,当我将代码推送到我的域时,它会说我为网站密钥提供了无效的域。

enter image description here

我不理解为什么网站密钥会无效,我已经反复检查了网站密钥,以确保它与我在ReCaptcha控制台中输入的域名匹配。是否有可能是IFrame不允许与ReCaptcha API通信?以下是该代码。

import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'dart:html' as html;
import 'dart:js' as js;

class platformViewRegistry {
  static registerViewFactory(String viewId, dynamic cb) {
    // ignore:undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(viewId, cb);
  }
}

class TestPlugin extends StatefulWidget {
  TestPlugin();

  _TestPluginState createState() => _TestPluginState();
}

class _TestPluginState extends State<TestPlugin> {
  String createdViewId = 'map_element';

  @override
  void initState() {
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
        createdViewId,
        (int viewId) => html.IFrameElement()
          ..width = MediaQuery.of(context).size.width.toString()
          ..height = MediaQuery.of(context).size.height.toString()
          ..srcdoc = """<!DOCTYPE html><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="mySitekey"
        data-callback="captchaCallback"></div>

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

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(color: Colors.grey[300], width: 1),
          borderRadius: BorderRadius.all(Radius.circular(5))),
      width: 200,
      height: 200,
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: HtmlElementView(
          viewType: createdViewId,
        ),
      ),
    );
  }
}

是否可以在不同的域名上设置一个独立的HTML站点,并通过该站点与Flutter Web进行界面交互以填写验证码?如果通过这样的接口,验证码是否仍然有效?

非常感谢您的帮助。


请检查此软件包 https://pub.dev/packages/flutter_recaptcha_v2 - Janvi Patel
你在本地运行了吗? - nhuluseda
我在本地主机和实际域名上都尝试过。 - Landon Stahl
3
这回答解决了你的问题吗?flutter_web如何实现RECAPTCHA? - Zujaj Misbah Khan
2个回答

2
我找到了一个适用于 reCaptcha v2 的解决方案:
在项目的根目录下创建一个名为 html 的文件夹,在该文件夹中创建一个名为 recaptcha.html 的文件。
<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="xxxxxxxxxxxxxxxxxxxxxxx"
        data-callback="captchaCallback"></div>

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

然后在资产下的pubspec.yaml文件中添加新文件夹html。
  assets:
    - fonts/
    - html/

最后,将_TestPluginState的initState()更改为:
    ui.platformViewRegistry.registerViewFactory(
      createdViewId,
      (int viewId) => html.IFrameElement()
        ..style.height = '100%'
        ..style.width = '100%'
        ..src = '/assets/html/recaptcha.html'
        ..style.border = 'none',
    );

重要提示:不要忘记将..srcdoc更改为..src


1
如果成功了,我应该把代码放在哪里,以便我的应用程序可以继续到下一页? - ali
我和@ali有同样的问题。你如何从HTML中获取验证码令牌并返回到Dart?有什么建议吗? - MSquare
以下是将程序相关内容从英语翻译成中文的结果:这对我来说可以让Dart获取验证码令牌:void initState() { // ignore: UNDEFINED_PREFIXED_NAME ui.platformViewRegistry.registerViewFactory( createdViewId, (int viewId) => html.IFrameElement() . . . ..src = '/assets/html/recaptcha.html' ..style.border = 'none'); html.window.onMessage.listen((msg) { Navigator.of(context).pop(msg.data); //msg.data is captcha token }); super.initState(); }在recaptcha.html中的captchaCallback(response)函数中包含:window.parent.postMessage(response, "*"); - MSquare

1
您可以尝试使用 g_recaptcha_v3 包。
注意:
  • 该包仅支持reCAPTCHA V3,不支持V2
  • 它仅适用于Flutter Web

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接