Solution to the problem that the Flutter project webview cannot be displayed on Android and iOS devices when loading web pages without HTTPS certificates

1. Problem description

The Flutter project uses Google's official webview library webview_flutter. When loading HTTPS web addresses such as self-signed certificates, invalid certificates, and no certificates, it will prompt that the certificate is invalid in the Android or PC browser, and it will be a blank page on the iOS device. In order to load the self-signed certificate For web pages, you need to bypass the HTTPS certificate verification of the webview control on iOS.

2. Environment

Android Studio version: 2022.1.1 Patch 2

Flutter version: 3.7.12

Dart SDK version: 2.19.6 

Dependent library webview_flutter version: 4.2.0

Xcode version: 14.3

3. Solution to HTTPS certificate verification on iOS devices in Flutter

1. Add webview_flutter repository dependency

In the pubspec.yaml file, find dev_dependencies, then change the line to add the dependent library, add the run command [flutter pub get], and download the library.

dev_dependencies:

  webview_flutter: ^4.2.0

After the download is completed, under the project structure External Libraries, you can see that webview_flutter has downloaded three projects in total, namely webview_flutter-4.2.0, webview_flutter_android-3.7.0, and webview_flutter_wkwebview-3.4.3, of which webview_flutter_wkwebview-3.4.3 is an iOS device. A webview component on the project, the source code that needs to be modified later is this project.

2. Modify the source code

Find External Libraries in the Flutter project directory structure, and expand Flutter Plugins in order——>webview_flutter_wkwebview-3.4.3——>ios.Classes

Then in the ios.Classes directory, find the FWFNavigationDelegateHostApi.m file, open the file, and add the following method in a new line after the @implementation FWFNavigationDelegate code:

@implementation FWFNavigationDelegate

//复制添加这个方法
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
    
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
        // 在这里进行自定义的身份验证逻辑
        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
    } else {
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
    }

    
}

Then save and run again.

Note: Because this modification method only modifies the local webview_flutter library source code, if you want to apply it to other people's projects, you need to export and upload the webview_flutter_wkwebview-3.4.3 library to GitHub or Gitee warehouse, and then pass it in the pubspec.yaml file Only by adding a dependent library to cover the source code of the original webview_flutter library can it be correctly applied to other people's projects. Export method: Click the library and right-click, find Open in——>Finder, and open it.

3. Cover the original library

The specific process is as follows:

In the pubspec.yaml file, find the dependency_overrides: node, then wrap the following content below it:

dependency_overrides:
  #注意这里不要顶格,格式务必确认正确,url地址为你自己修改过的源码库地址,
  webview_flutter_wkwebview:
    git:
      url: https://gitee.com/user/webview_flutter_wkwebview-3.4.3.git

Then run the [flutter pub get] command in the project root directory. You will be prompted to enter the username and password of the warehouse where your source code is located. After the download is completed, you will see that the source code library name has changed to your own warehouse name.

4. Xcode native engineering solves the HTTPS certificate verification solution on iOS devices

1. Import the WKWebview library

In the Xcode project, find the General interface, find [Frameworks, Libraries, and Embedded Content] in the interface below it, click the plus sign ➕ button on the right, search for WebKit in the pop-up search interface, and then select the searched WebKit.framework Library, click the Add button below, and the WKWebview dependent library is added.

 2. Add code

#import "ViewController.h"
#import <WebKit/WebKit.h>

//1、这里添加WKNavigationDelegate接口,为了实现WKWebView的证书校验方法
@interface ViewController () <WKNavigationDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //添加webview组件
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    CGRect frame = CGRectMake(0, 170, 400, 800);
    WKWebView *webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
    [self.view addSubview:webView];


    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //开始加载网页地址
    [webView loadRequest:request];
    
    //2、将当前类与WKNavigationDelegate接口监听进行绑定
    webView.navigationDelegate = self;
   
}

//3、重写didReceiveAuthenticationChallenge方法
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
    //在该方法当中添加如下代码,
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
    } else {
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
    }

}

@end

The code is divided into three steps. Once added, you can bypass the HTTPS web page certificate verification problem.

5. HTTPS certificate verification solution on Android devices

1. Create network_security_config.xml file

Open the Android project under the Flutter project in Android Studio, and then in the app directory, which is the main module module of the project, open the app->src->main->res directory in sequence, and create it in this directory. file xml, and then create the network_security_config.xml file in the xml directory. The file content is as follows:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

2. Reference the network_security_config.xml file

In the AndroidManifest.xml file, find the application node and add the android:networkSecurityConfig attribute

<application
        android:networkSecurityConfig="@xml/network_security_config"
>

The above is a solution for bypassing HTTPS certificate verification on Android devices.

Guess you like

Origin blog.csdn.net/u010263943/article/details/130789898