您现在的位置是:首页 >技术杂谈 >Flutter项目webview加载没有HTTPS证书的网页在Android和iOS设备上无法显示的解决方案网站首页技术杂谈

Flutter项目webview加载没有HTTPS证书的网页在Android和iOS设备上无法显示的解决方案

he先森 2024-06-17 11:27:51
简介Flutter项目webview加载没有HTTPS证书的网页在Android和iOS设备上无法显示的解决方案

一、问题描述

Flutter项目使用谷歌官方webview库 webview_flutter,加载自签名证书、证书失效、无证书等HTTPS网页地址时,在Android或pc浏览器中提示证书失效,在iOS设备上为空白页,为了加载自签名证书的网页,需要饶过iOS上的webview控件HTTPS证书校验。

二、环境

Android Studio版本:2022.1.1 Patch 2

Flutter版本:3.7.12

Dart SDK版本:2.19.6 

依赖库 webview_flutter 版本:4.2.0

Xcode版本:14.3

三、Flutter中解决iOS设备上HTTPS证书校验方案

1、添加webview_flutter版本库依赖

在pubspec.yaml文件中,找到dev_dependencies,然后换行添加依赖库,添加完运行命令【flutter pub get】,下载该库。

dev_dependencies:

  webview_flutter: ^4.2.0

下载完成后在项目结构External Libraries下,可以看到webview_flutter一共下载了三个项目,分别是webview_flutter-4.2.0、webview_flutter_android-3.7.0、webview_flutter_wkwebview-3.4.3,其中webview_flutter_wkwebview-3.4.3为iOS设备上的一个webview组件,后面所要修改源码的也就是这个工程。

2、修改源码

在Flutter工程目录结构中找到 External Libraries,依次展开Flutter Plugins——>webview_flutter_wkwebview-3.4.3——>ios.Classes

然后在ios.Classes目录下,找到FWFNavigationDelegateHostApi.m文件,打开该文件,在 @implementation FWFNavigationDelegate 代码以后换行添加以下方法:

@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);
    }

    
}

然后保存,再次运行即可。

注:因为该修改方式只是将本地的webview_flutter库源码做修改,要想应用到其他人的项目当中,需要把该 webview_flutter_wkwebview-3.4.3库导出上传到GitHub或者Gitee仓库,然后通过在pubspec.yaml文件中添加依赖库覆盖原webview_flutter库源码的方式,才能正确应用到其他人的项目中。导出方式:点击该库然后鼠标右键,找到 Open in——>Finder,打开即是。

3、覆盖原库

具体流程如下:

在pubspec.yaml文件中,找到 dependency_overrides:节点,然后在其下方换行添加以下内容:

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

然后在项目根目录下,运行【flutter pub get】命令,会提示输入你源码所在仓库的用户名和密码,下载完成后就能看到源码库名称已经变为你自己的仓库名称了。

四、Xcode原生工程解决iOS设备上HTTPS证书校验方案

1、导入WKWebview库

在Xcode项目中,找到General界面,在其下方界面找到【Frameworks,Libraries,and Embedded Content】,点击右侧的加号➕按钮,在弹出的搜索界面,搜索WebKit,然后选中搜索出来的WebKit.framework库,点击下面的Add按钮,WKWebview依赖库添加完成。

 2、添加代码

#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

代码一共分为三步,添加完即可实现饶过HTTPS网页证书校验问题。

五、Android设备上HTTPS证书校验解决方案

1、创建network_security_config.xml文件

在Android Studio中打开Flutter项目下的Android工程,然后在app的目录下,也就是项目的主module模块下,依次打开app——>src——>main——>res目录,在该目录下创建文件xml,然后在xml目录下,创建network_security_config.xml文件,文件内容如下:

<?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、引用network_security_config.xml文件

在AndroidManifest.xml文件中,找到application节点,添加android:networkSecurityConfig属性

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

以上为在Android设备饶过HTTPS证书校验方案。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。