【问题标题】:webview_flutter "Failed to validate the certificate chain" SSL handshake failed errorwebview_flutter“验证证书链失败”SSL握手失败错误
【发布时间】:2019-12-06 18:24:31
【问题描述】:

我遇到了这个问题,并在 this 的帮助下解决了这个问题,但我花了一些时间才弄清楚代码应该放在哪里,因为 flutter_webview_pugin 和 之间的代码有点不同>webview_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 并不能保证客户端通过该域访问的每个服务最终都将使用相同的来源,所以在我的情况下,我试图使用 RTSP 连接到服务器以流式传输安全摄像头,但它是“101 切换协议”实现了对没有有效 SSL 的不同端口的第一个请求。

【问题讨论】:

    标签: ssl flutter webview


    【解决方案1】:

    你可以使用我的插件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 导入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 2015-06-05
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多