首頁 > 軟體

Flutter設定代理抓包實現過程詳解

2023-02-14 06:00:04

背景

在開發Flutter中,我們經常需要對網路請求進行偵錯,而Flutter自帶的devtool的network又不太好用,有時會出現請求成功,但是又看不到response返回(難道是我姿勢不對?)。於是我就嘗試通過抓包來檢視請求

工具準備

  • 安裝charles
  • 有時我們需要抓https的請求,此時用charles抓包的內容是加密的,看不到明文,這時候需要安裝下Charles的證書來解決。點選help > SSL Proxying > Install Charles Root Certificate,安裝到系統的鑰匙串中。(這裡借下了光哥小冊裡的截圖)

點選證書,將信任選項改成始終信任

開啟charles的代理。開啟後,確認Proxy索引標籤與下方畫紅線的地方顯示一樣

設定Flutter代理

完成工具準備後,由於Flutter預設不走系統代理,所以我們還需要手動在Flutter專案中設定代理,charles才能正確抓到包。這裡提供兩種方案,一種是在請求庫的設定裡設定代理,另一種是利用Flutter原生的類來完成

方式一、http請求庫設定代理

dio設定代理

flutter專案裡通常用dio庫做http請求,我們可以通過dio的httpClientAdapter屬性設定我們的本地代理。程式碼如下:

import 'package:dio/dio.dart';
var dio = Dio();
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
  (client) {
  client.findProxy = (uri) {
    return 'PROXY localhost:8888';
  };
  client.badCertificateCallback =
    (X509Certificate cert, String host, int port) => true; //忽略證書
};

其中client.findProxy函數用來返回我們的代理介面,charles的預設的系統代理埠是8888,所以這裡設定成

PROXY localhost:8888就可以了。下面一句client.badCertificateCallback函數也很關鍵,如果不進行設定,charles在抓包https請求時會出現下圖錯誤:

這個錯誤產生的原因,經我查閱網上資料是因為Flutter請求https時用的是自己的CA認證證書,所以charles在認證證書時沒有通過,導致抓包錯誤。所以我們直接通過client.badCertificateCallback函數返回true來忽略證書就好了。

web_socket_channel設定代理

有了上面dio的設定後,還不夠,因為我們的websocket請求還是無法抓包。如果你專案中需要抓取websocket,可以使用web_socket_channel這個庫。需要注意的是這個庫不能從官網拉取,因為官方的web_socket_channel的還不支援代理,我在官方的程式碼倉庫看到有幾個與支援代理相關的pr請求,但是官方都還沒有進行合併分支,所以我就自己fork倉庫修改了一下,我們可以改成以下方式進行安裝:

dependencies:
  web_socket_channel:
      git:
        url: https://github.com/IFreeOvO/web_socket_channel.git
        ref: master

然後我們開始設定web_socket_channel,不過有了之前設定dio的經驗後,我們設定web_socket_channel也是使用了差不多的思路,程式碼如下:

import 'package:web_socket_channel/io.dart';
// 建立一個自己的HttpClient物件
SecurityContext ctx = SecurityContext.defaultContext;
HttpClient client = HttpClient(context: ctx)
  ..findProxy = ((uri) {
    return 'PROXY localhost:8888';
  })
  ..badCertificateCallback = (cert, host, port) {
  return true;
};
_channel = IOWebSocketChannel.connect(
  'wss://xxx.com',
  customClient: client, // 使用客製化的HttpClient
);

方式二、重寫原生方法

在入口檔案main.dart裡定義一個HttpOverrides的子類,重寫它的createHttpClient方法。原理也是一樣的,把findProxybadCertificateCallback方法進行替換。然後掛載到全域性。

// 重寫HttpOverrides
class MyHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext? context) {
    var http = super.createHttpClient(context);
    http.findProxy = (uri) {
      return 'PROXY localhost:8888';
    };
    http.badCertificateCallback =
        (X509Certificate cert, String host, int port) => true;
    return http;
  }
}
void main() {
  HttpOverrides.global = MyHttpOverrides(); // 使用自己的HttpOverrides類
  runApp(MyApp());
}

這種方案的好處是不受第三方請求庫限制,設定完後httpswebsocket都能正確抓包。效果如圖:

以上就是Flutter設定代理抓包實現過程詳解的詳細內容,更多關於Flutter設定抓包的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com