WebView_flutter "验证证书链失败" SSL 握手失败错误。

7
我曾经遇到过这个问题,通过这个方法解决了。但是因为在flutter_webview_pluginwebview_flutter之间存在一些代码差异,所以我花了一些时间来找出在哪里放置代码。这篇教程将展示如何在MacOS上实现webview_flutter的这种方法(在Windows上,文件可能会有所不同)。
1- 将此文件夹/Volumes/.../Flutter/SDK/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter-0.3.10+4复制到项目根目录的上一级路径中,例如:
如果这是您的项目:/Volumes/Depo/MyProject/ 那么放置插件文件夹的位置可以方便地设置为这里:/Volumes/Depo/edited/ 2- 接着打开这个文件/Volumes/Depo/edited/webview_flutter-0.3.10+4/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
并添加这行代码:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  handler.proceed();
}

修改 internalCreateWebViewClient 函数。 修改后的函数应如下所示:

private WebViewClient internalCreateWebViewClient() {
    return new WebViewClient() {
      @TargetApi(Build.VERSION_CODES.N)
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, request);
      }

      @Override
      public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();
        }

      @Override
      public void onPageFinished(WebView view, String url) {
        FlutterWebViewClient.this.onPageFinished(view, url);
      }
    };
  }

3- 添加这些导入

import android.net.http.SslError;
import android.webkit.SslErrorHandler;

由于这种方法绕过了SSL,因此不建议在生产环境中使用。

即使服务器的SSL证书有效,这个问题仍会发生。 因为一个有效的SSL并不能保证客户端通过该域名访问的每个服务都会使用相同的来源(origin)。 在我的情况下,我尝试连接到服务器以使用RTSP流式传输安全摄像头,但是第一次请求到达另一个没有实现有效SSL的端口时返回了"101 Switching Protocols"错误消息。

1个回答

9
您可以使用我的插件flutter_inappwebview。它包含许多事件,包括用于管理SSL错误和SSL客户端证书请求的事件:
  • onReceivedServerTrustAuthRequest:当WebView需要执行服务器信任认证(证书验证)时触发的事件。在Android上,这是使用onReceivedSslError事件实现的。
  • onReceivedClientCertRequest:通知主机应用程序处理SSL客户端证书请求。
因此,在您的情况下,您只需要使用onReceivedServerTrustAuthRequest事件,并简单地返回ServerTrustAuthResponse(action: ServerTrustAuthResponseAction.PROCEED);
import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialUrl: "https://myUrl",
                    initialHeaders: {},
                    initialOptions: InAppWebViewWidgetOptions(
                        inAppWebViewOptions: InAppWebViewOptions(
                          debuggingEnabled: true,
                        ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

                    },
                    onLoadStop: (InAppWebViewController controller, String url) {

                    },
                    onReceivedServerTrustAuthRequest: (InAppWebViewController controller, ServerTrustChallenge challenge) async {
                      return ServerTrustAuthResponse(action: ServerTrustAuthResponseAction.PROCEED);
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

其中"https://myUrl"是您的网址。


提醒一下,这个例子缺少了InAppWebViewWidgetOptions的导入。 - Steven Linn
这个可行!谢谢。这是更新后的代码:onReceivedServerTrustAuthRequest: (InAppWebViewController controller, URLAuthenticationChallenge challenge) async { return ServerTrustAuthResponse(action: ServerTrustAuthResponseAction.PROCEED); } - mahfuz
@StevenLinn现在需要initialOptions InAppWebViewGroupOptions。那么我们需要在这里传递什么? - Nifal Nizar
1
@Lorenzo 仍然无法在IOS上运行。 - Nifal Nizar
插件更新版本为flutter_inappwebview: ^5.4.3+7。=> onReceivedServerTrustAuthRequest: (controller, challenge) async { return new ServerTrustAuthResponse( action: ServerTrustAuthResponseAction.PROCEED); }, - ALEXANDER LOZANO
我使用 flutter_inappwebview: ^5.7.1+2,但在 iOS 上与 Charles 一起使用时无法正常工作,但此时我可以从我的应用程序中的其他位置调用它(Dio)。 - EvGeniy Ilyin

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