pichillilorenzo / flutter_inappwebview

A Flutter plugin that allows you to add an inline webview, to use a headless webview, and to open an in-app browser window.
https://inappwebview.dev
Apache License 2.0
3.15k stars 1.47k forks source link

Cloudflare Turnstile failure #1738

Open ttb-inc opened 1 year ago

ttb-inc commented 1 year ago

Environment

Technology Version
Flutter version Flutter version 3.10.6 on channel stable
Plugin version 6.0.0-beta.24+1
Android version Android 12
iOS version iOS 16.x
macOS version 13.4.1 (c)(22F770820d)
Xcode version Build 14E300c

Device information:

Description

I am loading a webpage with "Cloudflare Turnstile" applied.

However, the webview of flutter_inappwebview seems to have a security error.

All other browsers (PC, Mobile) are passing fine.

I would like to know what the problem is.

If anyone has any knowledge about this issue, please help me.

Thank you.

Steps to reproduce

My InAppWebViewSettings

var inAppWebViewSettings = InAppWebViewSettings(
  useShouldOverrideUrlLoading: true,

  transparentBackground: true,
  javaScriptCanOpenWindowsAutomatically: true,
  allowFileAccessFromFileURLs: true,
  allowUniversalAccessFromFileURLs: true,

  verticalScrollBarEnabled: false,

  horizontalScrollBarEnabled: false,

  supportMultipleWindows: true,

  useHybridComposition: true,

  isInspectable: true,
);

Test Page https://app.1inch.io/

Images

Stacktrace/Logcat

github-actions[bot] commented 1 year ago

👋 @ttb-inc

NOTE: This comment is auto-generated.

Are you sure you have already searched for the same problem?

Some people open new issues but they didn't search for something similar or for the same issue. Please, search for it using the GitHub issue search box or on the official inappwebview.dev website, or, also, using Google, StackOverflow, etc. before posting a new one. You may already find an answer to your problem!

If this is really a new issue, then thank you for raising it. I will investigate it and get back to you as soon as possible. Please, make sure you have given me as much context as possible! Also, if you didn't already, post a code example that can replicate this issue.

In the meantime, you can already search for some possible solutions online! Because this plugin uses native WebView, you can search online for the same issue adding android WebView [MY ERROR HERE] or ios WKWebView [MY ERROR HERE] keywords.

Following these steps can save you, me, and other people a lot of time, thanks!

ludowkm commented 1 year ago

@ttb-inc Did you have any solution for it yet ?

ttb-inc commented 1 year ago

@ttb-inc Did you have any solution for it yet ?

We haven't solved it yet. We're still working on it.

vidorge commented 10 months ago

Hello @ttb-inc @ludowkm

Did you have any luck in fixing this issue? It's a major blocker for us and I am considering reaching out to someone at Cloudflare.

ttb-inc commented 10 months ago

Hello @ttb-inc @ludowkm

Did you have any luck in fixing this issue? It's a major blocker for us and I am considering reaching out to someone at Cloudflare.

I haven't solved it yet either. ㅡ,ㅡ; If you have any good news, please share. Thank you.

RMatushkin commented 10 months ago

I'm facing the same problem.

migueldemoura commented 10 months ago

Hi everyone, I'm an engineer working on Turnstile at Cloudflare.

I'm afraid I'm unable to reproduce the issue, could you follow https://developers.cloudflare.com/turnstile/frequently-asked-questions/#how-can-i-obtain-the-ray-id-or-qr-code-for-troubleshooting and post the rayID or QR code here so I can follow-up?

RMatushkin commented 10 months ago

Hi everyone, I'm an engineer working on Turnstile at Cloudflare.

I'm afraid I'm unable to reproduce the issue, could you follow https://developers.cloudflare.com/turnstile/frequently-asked-questions/#how-can-i-obtain-the-ray-id-or-qr-code-for-troubleshooting and post the rayID or QR code here so I can follow-up?

Hello! Thank you very much for helping to figure out the problem! I will try to assist; for me, it's quite straightforward, I turn on my personal VPN, which operates through an IP address of a server on DigitalOcean, attempt to access my app that uses this WebView plugin, open the link https://dash.cloudflare.com/ just to reach the point where Cloudflare shows me the robot check. I try to pass it and then I get errors in the logs, below I attach typical logs from the console. In turn, I tried to look at the traffic in a regular browser while passing this check and saw that the browser processes resources whose address starts with blob:https. But in the logs, I do not see that the WebView plugin tries to load such resources in any way. It seems like WebView can't work with blob:https right out of the box.

How to get to the check doesn't matter at all, I just found the fastest way for myself to open the Cloudflare check.

Logs:

[InAppWebViewController] (iOS) WebView ID 0 calling "onLoadStop" using {url: https://dash.cloudflare.com/} [InAppWebViewController] (iOS) WebView ID 0 calling "shouldOverrideUrlLoading" using {hasGesture: null, sourceFrame: {securityOrigin: {host: dash.cloudflare.com, protocol: https, port: 0}, request: {headers: {}, networkServiceType: 0, assumesHTTP3Capable: false, attribution: 0, url: https://dash.cloudflare.com/, allowsExpensiveNetworkAccess: true, httpShouldUsePipelining: true, method: GET, timeoutInterval: 2147483647.0, body: null, allowsCellularAccess: true, httpShouldHandleCookies: true, cachePolicy: 0, mainDocumentURL: null, allowsConstrainedNetworkAccess: true}, isMainFrame: true}, isForMainFrame: false, isRedirect: null, targetFrame: {request: {networkServiceType: 0, assumesHTTP3Capable: false, url: , allowsConstrainedNetworkAccess: true, cachePolicy: 0, httpShouldHandleCookies: true, attribution: 0, timeoutInterval: 2147483647.0, body: null, mainDocumentURL: null, headers: {}, method: GET, allowsExpensiveNetworkAccess: true, httpShouldUsePipelining: true, allowsCellularAccess: true}, isMainFrame: false,... [InAppWebViewController] (iOS) WebView ID 0 calling "shouldOverrideUrlLoading" using {isForMainFrame: false, shouldPerformDownload: false, targetFrame: {request: {attribution: 0, body: null, httpShouldHandleCookies: true, timeoutInterval: 2147483647.0, mainDocumentURL: null, method: GET, allowsCellularAccess: true, cachePolicy: 0, networkServiceType: 0, allowsExpensiveNetworkAccess: true, httpShouldUsePipelining: true, assumesHTTP3Capable: false, url: , headers: {}, allowsConstrainedNetworkAccess: true}, securityOrigin: {host: challenges.cloudflare.com, port: 0, protocol: https}, isMainFrame: false}, hasGesture: null, request: {method: GET, headers: {}, allowsConstrainedNetworkAccess: true, networkServiceType: 0, cachePolicy: 0, timeoutInterval: 2147483647.0, mainDocumentURL: https://dash.cloudflare.com/, httpShouldHandleCookies: true, httpShouldUsePipelining: true, url: about:blank, attribution: 0, allowsCellularAccess: true, assumesHTTP3Capable: false, body: null, allowsExpensiveNetworkAccess: true}, navigat... [InAppWebViewController] (iOS) WebView ID 0 calling "shouldOverrideUrlLoading" using {sourceFrame: {securityOrigin: {protocol: https, port: 0, host: challenges.cloudflare.com}, request: {cachePolicy: 0, url: https://challenges.cloudflare.com/cdn-cgi/challenge-platform/h/g/turnstile/if/ov2/av0/rcv0/0/6vq0n/0x4AAAAAAADnPIDROrmt1Wwj/light/normal, allowsConstrainedNetworkAccess: true, headers: {}, allowsExpensiveNetworkAccess: true, attribution: 0, httpShouldUsePipelining: true, assumesHTTP3Capable: false, timeoutInterval: 2147483647.0, networkServiceType: 0, allowsCellularAccess: true, httpShouldHandleCookies: true, mainDocumentURL: null, method: GET, body: null}, isMainFrame: false}, isRedirect: null, request: {method: GET, mainDocumentURL: https://dash.cloudflare.com/, httpShouldHandleCookies: true, httpShouldUsePipelining: true, allowsExpensiveNetworkAccess: true, networkServiceType: 0, cachePolicy: 0, allowsCellularAccess: true, attribution: 0, allowsConstrainedNetworkAccess: true, timeoutInterval: 2147483647... [InAppWebViewController] (iOS) WebView ID 0 calling "shouldOverrideUrlLoading" using {navigationType: -1, isForMainFrame: false, request: {networkServiceType: 0, headers: {}, body: null, allowsConstrainedNetworkAccess: true, httpShouldUsePipelining: true, assumesHTTP3Capable: false, mainDocumentURL: https://dash.cloudflare.com/, cachePolicy: 0, attribution: 0, timeoutInterval: 2147483647.0, allowsCellularAccess: true, httpShouldHandleCookies: true, method: GET, allowsExpensiveNetworkAccess: true, url: about:blank}, hasGesture: null, isRedirect: null, sourceFrame: {securityOrigin: {port: 0, protocol: https, host: challenges.cloudflare.com}, request: {body: null, url: https://challenges.cloudflare.com/cdn-cgi/challenge-platform/h/g/turnstile/if/ov2/av0/rcv0/0/6vq0n/0x4AAAAAAADnPIDROrmt1Wwj/light/normal, allowsExpensiveNetworkAccess: true, allowsCellularAccess: true, httpShouldHandleCookies: true, timeoutInterval: 2147483647.0, attribution: 0, allowsConstrainedNetworkAccess: true, networkServiceType: 0, mainDocum... [InAppWebViewController] (iOS) WebView ID 0 calling "shouldOverrideUrlLoading" using {isRedirect: null, sourceFrame: {securityOrigin: {protocol: https, port: 0, host: challenges.cloudflare.com}, request: {allowsExpensiveNetworkAccess: true, mainDocumentURL: null, headers: {}, cachePolicy: 0, httpShouldHandleCookies: true, networkServiceType: 0, url: https://challenges.cloudflare.com/cdn-cgi/challenge-platform/h/g/turnstile/if/ov2/av0/rcv0/0/6vq0n/0x4AAAAAAADnPIDROrmt1Wwj/light/normal, method: GET, body: null, allowsCellularAccess: true, allowsConstrainedNetworkAccess: true, httpShouldUsePipelining: true, assumesHTTP3Capable: false, timeoutInterval: 2147483647.0, attribution: 0}, isMainFrame: false}, isForMainFrame: false, navigationType: -1, hasGesture: null, request: {allowsConstrainedNetworkAccess: true, httpShouldUsePipelining: true, httpShouldHandleCookies: true, networkServiceType: 0, headers: {}, timeoutInterval: 2147483647.0, allowsExpensiveNetworkAccess: true, mainDocumentURL: https://dash.cloudflare.c... [InAppWebViewController] (iOS) WebView ID 0 calling "onConsoleMessage" using {messageLevel: 1, message: CgVD} [InAppWebViewController] (iOS) WebView ID 0 calling "onConsoleMessage" using {messageLevel: 1, message: SPcR} [InAppWebViewController] (iOS) WebView ID 0 calling "onConsoleMessage" using {messageLevel: 1, message: } [InAppWebViewController] (iOS) WebView ID 0 calling "onConsoleMessage" using {messageLevel: 1, message: The next request for the Private Access Token challenge may return a 401 and show a warning in console.} [InAppWebViewController] (iOS) WebView ID 0 calling "onConsoleMessage" using {messageLevel: 1, message: The next request for the Private Access Token challenge may return a 401 and show a warning in console.} [InAppWebViewController] (iOS) WebView ID 0 calling "onConsoleMessage" using {message: [Cloudflare Turnstile] Cannot find Widget cf-chl-widget-6vq0n, consider using turnstile.remove() to clean up a widget.., messageLevel: 2} [InAppWebViewController] (iOS) WebView ID 0 calling "shouldOverrideUrlLoading" using {targetFrame: {request: {url: https://dash.cloudflare.com/, httpShouldUsePipelining: true, timeoutInterval: 2147483647.0, headers: {}, httpShouldHandleCookies: true, assumesHTTP3Capable: false, body: null, allowsExpensiveNetworkAccess: true, method: GET, allowsConstrainedNetworkAccess: true, cachePolicy: 0, networkServiceType: 0, mainDocumentURL: null, attribution: 0, allowsCellularAccess: true}, securityOrigin: {port: 0, host: dash.cloudflare.com, protocol: https}, isMainFrame: true}, sourceFrame: {securityOrigin: {host: dash.cloudflare.com, protocol: https, port: 0}, isMainFrame: true, request: {attribution: 0, mainDocumentURL: null, assumesHTTP3Capable: false, httpShouldHandleCookies: true, httpShouldUsePipelining: true, body: null, url: https://dash.cloudflare.com/, allowsExpensiveNetworkAccess: true, cachePolicy: 0, networkServiceType: 0, timeoutInterval: 2147483647.0, allowsConstrainedNetworkAccess: true, method: GET, he...

Screenshot of the check page:

Screenshot 2023-11-08 at 14 48 05
migueldemoura commented 10 months ago

Thanks, @RMatushkin!

Screenshot of the check page:

What happens when you click the "Verify you are human" button? Do you get a failure icon and text?

I tried to look at the traffic in a regular browser while passing this check and saw that the browser processes resources whose address starts with blob:https.

We used to have navigations to blob: URLs but found those were incompatible with this lib when used together with navigation delegates. What you see in Dev Tools right now isn't a fetch/XHR, and as far as we're aware those don't pose an issue.

I'm unable to reproduce the issue, both with a basic example of flutter_inappwebview, https://github.com/pichillilorenzo/flutter_browser_app, and I'm afraid I don't see what the issue you're experiencing might be by looking at the logs you provided.

Do you only experience the issue on iOS? I see the reports about Android, but I can't reproduce those, even with the current latest few WebView versions.

RMatushkin commented 10 months ago

Hey @migueldemoura!

What happens when you click the "Verify you are human" button? Do you get a failure icon and text?

After clicking, a looping loading appears, in other words, nothing happens for a very long time. Then the square for clicking appears again.

We used to have navigations to blob: URLs but found those were incompatible with this lib when used together with navigation delegates. What you see in Dev Tools right now isn't a fetch/XHR, and as far as we're aware those don't pose an issue.

Interesting fact, I really hope that blob resources really don’t have any effect.

Do you only experience the issue on iOS? I see the reports about Android, but I can't reproduce those, even with the current latest few WebView versions.

I use exclusively iOS devices, I have no idea how the CloudFlare check behaves on Android devices.


Plugin version: v6.0.0-beta.25

WebView settings:

initialSettings: InAppWebViewSettings(
  preferredContentMode: UserPreferredContentMode.MOBILE,
  transparentBackground: true,
  supportZoom: false,
  verticalScrollBarEnabled: false,
  horizontalScrollBarEnabled: false,
  javaScriptCanOpenWindowsAutomatically: true,
  allowUniversalAccessFromFileURLs: true,
  accessibilityIgnoresInvertColors: true,
  isFraudulentWebsiteWarningEnabled: false,
  allowsAirPlayForMediaPlayback: false,
  allowsPictureInPictureMediaPlayback: false,
  allowsInlineMediaPlayback: true,
  geolocationEnabled: false,
)

Used link: https://dash.cloudflare.com


Here, I specifically recorded a short video that shows the problem in action:

https://github.com/pichillilorenzo/flutter_inappwebview/assets/54648323/41c0345c-8228-47c6-be3e-f0a79d8dabd8

And here is logs file from the video: logs.txt

Diniboy1123 commented 10 months ago

I can reproduce this on Android using my own test app and the above mentioned flutter_browser_app example. I could see the following in the developer console: Uncaught SecurityError: Failed to read a named property 'flutter_inappwebview' from 'Window': Blocked a frame with origin "https://challenges.cloudflare.com" from accessing a frame with origin "https://mydomain.tld". Protocols, domains, and ports must match. I assume this should be related. I see the captcha, click on it, it seems to succeed and then the challenge page just reloads once again.

Ray ID: 825c10fd4f12c2ca

AlexDochioiu commented 10 months ago

Anyone found a solution on this? I am encountering a similar issue (where the captcha gets rejected every single time for everyone that tried)

RMatushkin commented 10 months ago

Anyone found a solution on this? I am encountering a similar issue (where the captcha gets rejected every single time for everyone that tried)

I guess only @migueldemoura can help here.

xSILENCEx commented 9 months ago

Any updates?

pichillilorenzo commented 9 months ago

It should be fixed now for iOS on the latest release.

Instead, for Android WebView, it seems the problem could be related to the X-Requested-With HTTP header sent automatically by native WebView for each HTTP request: https://community.cloudflare.com/t/turnstile-always-fails-in-a-webview/423520/5 Currently, there is no official Android WebView API to disable this HTTP header, as it should be already removed starting from androidx.webkit:webkit:1.6.0-alpha02:

@migueldemoura I don't know if one of you has managed to resolve Android WebView related problems in the past. Other people seem to have a similar problem with Android WebView: https://community.cloudflare.com/search?q=Android%20WebView Any advice is welcome, thanks!

RMatushkin commented 9 months ago

@pichillilorenzo Thank you very much for taking the time to fix this error, we appreciate it <3

RMatushkin commented 9 months ago

It should be fixed now for iOS on the latest release.

I just took the source code from the commit, rebuilt my iOS app based on this version, and saw that the issue with Cloudflare Turnstile hasn't been resolved. I looked at the changes you made, but I don't understand how they relate to the current issue. You only fixed the logging in the file ConsoleLogJS.swift. Will there be another commit that fixes the problem?

pichillilorenzo commented 9 months ago

Try to run flutter pub upgrade with latest 6 version . For some reason, the console wrapper implemented for iOS seemed to cause the issue, I don’t know why. I tried removing completely that implementation and it worked, so I tried to deep understand what was causing the issue and I came up with that.

pichillilorenzo commented 9 months ago

I tested both links https://dash.cloudflare.com/ and https://app.1inch.io/ on real iPhone and it worked. Without this fix, I was having same issue.

pichillilorenzo commented 9 months ago

Here is my screen recording:

RPReplay_Final1701465845

Without that fix, I was getting Cloudflare verification to fail every time, for both URLs.

Test code:

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();

  if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
    await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
  }

  runApp(const MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final GlobalKey webViewKey = GlobalKey();

  InAppWebViewController? webViewController;
  InAppWebViewSettings settings =
  InAppWebViewSettings(isInspectable: kDebugMode);

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Example'),
          actions: [
            ElevatedButton(onPressed: () {
              webViewController?.loadUrl(
                  urlRequest: URLRequest(url: WebUri('https://app.1inch.io/')));
            }, child: const Text('Try app.1nch.io')),
            ElevatedButton(onPressed: () {
              webViewController?.loadUrl(
                  urlRequest: URLRequest(url: WebUri('https://dash.cloudflare.com/')));
            }, child: const Text('Try dash.cloudflare.com'))
          ],
        ),
        body: Column(children: <Widget>[
          Expanded(
              child: InAppWebView(
                key: webViewKey,
                initialUrlRequest:
                URLRequest(url: WebUri("https://dash.cloudflare.com/")),
                initialSettings: settings,
                onWebViewCreated: (InAppWebViewController controller) {
                  webViewController = controller;
                },
              )),
        ]));
  }
}
AlexDochioiu commented 9 months ago

It should be fixed now for iOS on the latest release.

Instead, for Android WebView, it seems the problem could be related to the X-Requested-With HTTP header sent automatically by native WebView for each HTTP request: https://community.cloudflare.com/t/turnstile-always-fails-in-a-webview/423520/5 Currently, there is no official Android WebView API to disable this HTTP header, as it should be already removed starting from androidx.webkit:webkit:1.6.0-alpha02:

@migueldemoura I don't know if one of you has managed to resolve Android WebView related problems in the past. Other people seem to have a similar problem with Android WebView: https://community.cloudflare.com/search?q=Android%20WebView Any advice is welcome, thanks!

Hmm, I tried the official webview flutter plugin and from what I remember Turnstile was passing fine there on Android.

RMatushkin commented 9 months ago

@pichillilorenzo Thank you very much for your help! Indeed, after I ran the flutter pub upgrade command, the problem was resolved even on the iOS simulator.

pichillilorenzo commented 9 months ago

@RMatushkin 👍 that’s because I published a new minor version with the fix on the iOS-specific implementation package, but the main plugin has not been updated. Newer plugin version has been implemented as a Federated Flutter plugin.

@AlexDochioiu hmm I will try and check again.

migueldemoura commented 9 months ago

It should be fixed now for iOS on the latest release.

Instead, for Android WebView, it seems the problem could be related to the X-Requested-With HTTP header sent automatically by native WebView for each HTTP request: https://community.cloudflare.com/t/turnstile-always-fails-in-a-webview/423520/5 Currently, there is no official Android WebView API to disable this HTTP header, as it should be already removed starting from androidx.webkit:webkit:1.6.0-alpha02:

@migueldemoura I don't know if one of you has managed to resolve Android WebView related problems in the past. Other people seem to have a similar problem with Android WebView: https://community.cloudflare.com/search?q=Android%20WebView Any advice is welcome, thanks!

@pichillilorenzo I just read your console patch for the iOS version, and indeed that was likely the root cause for the previous issue. Can also confirm that the presence of X-Requested-With should not cause the Turnstile failure for Android WebViews. We do have substancial traffic from these, so I presume there's some modifications being applied which would lead to the failures.

I was unable to reproduce this on Android, but would like to get this working for you all. When it fails, could you submit feedback via the Having trouble? dialog that appears when it fails and adding https://github.com/pichillilorenzo/flutter_inappwebview/issues/1738 to the description?

image
pichillilorenzo commented 9 months ago

Fixed also on Android now! You can update to the newly published plugin version 6.0.0-rc.1.

@migueldemoura the error was caused by the same code spot on Android. I don't know why the javascript wrapper around the window.console was causing the issue. It doesn't make any sense to me, but it seems the javascript code used by CloudFlare is doing something with the window.console object. Somehow, If the window.console functions (log, error, etc.) are wrapped with a function that is long X characters (I don't know the maximum number of chars but I mean literally the string characters), it just breaks. In fact, my fixes are just about moving out the wrapper code the needed logic.

Here is just an example of what I'm talking about. Think that you want to wrap the console.log function for whatever reason, you can do something like:

var oldConsoleLog = console.log;
console.log = function() {
    var message = '';
    for (var i in arguments) {
        message += message === '' ? arguments[i] : ' ' + arguments[i];
    }
    oldConsoleLog.apply(null, arguments, 'myValue');
}

This wrapping would cause the issue that we were having here.

Instead, this code would simply work:

var oldConsoleLog = console.log;
console.log = function() {
    oldConsoleLog.apply(null, arguments, 'myValue');
}

I also tried adding just code comments or whitespaces, and it would still break, so it seems like it depends on how many characters the log functions of the window.console object are made up of.

As I said, it doesn't make any sense to me on why this would cause the issue on Cloudflare. 🤷‍♂️

ttb-inc commented 9 months ago

I checked the new version 6.0.0-rc.1, and it works well on both Android and iOS. Thank you very much.

endyquang commented 7 months ago

I still see this error on newest version 6.0.0 on iOS (Flutter 3.16.5, iOS 16.x). It works on Android but stuck forever on iOS.

Steps to produce:

After adding a UserScript to override console.clear = (() => {});. Open the inspector, select preserve log, this is the stack trace leading to the console wrapper.

Screenshot 2024-01-30 at 16 49 47

@pichillilorenzo what about an option to disable this console wrapper? An additional reason is on Android, this wrapper currently converts all arguments into string, which makes it difficult to debug, because we can't see the logged objects properly on the chrome inspector.

a00012025 commented 7 months ago

Hi, I can reproduce this issue on iOS using latest version of the library, with this URL: https://etherscan.io/myaccount

pichillilorenzo commented 7 months ago

Thanks for the reports, I will check it as soon as possible.

@endyquang about Android, I should be able to change the current wrapper without impacting the Chrome debug console. The current implementation was done that way to match the same onConsoleMessage event we have on iOS and macOS. It seems that on Android, the native WebView event that is responsible for getting console messages will take only the first argument. So, that’s the reason about the current implementation.

rafagazani commented 4 months ago

import 'dart:developer';

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

class CloudFlareTurnstileWidget extends StatelessWidget { final Function(bool) setCaptcha; const CloudFlareTurnstileWidget({required this.setCaptcha, Key? key}) : super(key: key);

@override Widget build(BuildContext context) { return SizedBox( height: 85, width: 330, child: InAppWebView( initialData: InAppWebViewInitialData( data: htmlContent, ), onConsoleMessage: (controller, consoleMessage) { if (consoleMessage.messageLevel == ConsoleMessageLevel.LOG) { setCaptcha(true); log('tipo: ${consoleMessage.messageLevel}'); log('mensagem: ${consoleMessage.message}'); } }, // onLoadStop: (controller, url) async { // await controller.evaluateJavascript(source: 'window._turnstileCb();'); // }, ), ); }

final String htmlContent = ''' <!DOCTYPE html>

'''; }

image

rafagazani commented 4 months ago

Código de erro: 600010 RayId: 87ca1ebbeb5400ea

rafagazani commented 4 months ago

If I try to run the script directly in the index.html, without going through the flutter it works: image

Nika0000 commented 4 months ago

A few days ago I published the Cloudflare Turnstile widget on pub.dev.

https://pub.dartlang.org/packages/cloudflare_turnstile

rafagazani commented 4 months ago

@Nika0000 Thanks, it worked perfectly

stickeerehan commented 2 months ago

Having this issue using 6.0.0. My settings are as follows:

InAppWebViewSettings(
    useShouldOverrideUrlLoading: true,
    mediaPlaybackRequiresUserGesture: false,
    useShouldInterceptAjaxRequest: true,
    disableVerticalScroll: false,
    useHybridComposition: true,
    allowsInlineMediaPlayback: true,
    javaScriptCanOpenWindowsAutomatically: true,
    allowFileAccessFromFileURLs: true,
    allowUniversalAccessFromFileURLs: true,
    isInspectable: true,
  );

Initialised by:

InAppWebView(
          gestureRecognizers: {Factory(() => EagerGestureRecognizer())},
          initialUrlRequest: URLRequest(url: WebUri(url)),
          initialSettings: settings,
          onWebViewCreated: (controller) async {
            webViewController = controller;
            await CookieManager.instance().deleteAllCookies();
          },
          onLoadStop: (controller, url) async {
            // Some checks looking at the page.
          },
          shouldOverrideUrlLoading: (controller, action) async {
            return NavigationActionPolicy.ALLOW;
          },

Seems like other web views also have similar issues: https://community.cloudflare.com/t/turnstile-no-longer-working-inside-of-ios-apps-in-wkwebview/637940/8

Is there a similar alternative for the in app web view to use for originWhitelist in case that is the issue?

migueldemoura commented 2 months ago

Hey @stickeerehan, originWhitelist is usually the issue, otherwise it should work as we test against this specific implementation w/ its defaults.

stickeerehan commented 2 months ago

Looks like in my case the culprit after trial and error was the setting 'useShouldInterceptAjaxRequest' - having this breaks the Cloudflare turnstile. Can confirm it works with the default settings