You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter应用调用Docker API时如何使用三类SSL/TLS证书发送请求

Flutter调用带SSL/TLS双向认证的Docker Engine API解决方案

前置准备

  • 将ca.pem、cert.pem、key.pem三个凭证文件放入项目的assets目录下
  • 在pubspec.yaml中声明资源依赖:
flutter:
  assets:
    - assets/ca.pem
    - assets/cert.pem
    - assets/key.pem
  • 安装dio依赖,执行命令:flutter pub add dio

核心实现代码

核心思路是通过Dart原生的SecurityContext加载三类凭证,再将自定义的安全上下文绑定到请求客户端中,完整示例如下:

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/services.dart';

class DockerApiClient {
  late Dio _dio;
  final String baseUrl = "https://65.0.95.227:2376";

  // 初始化客户端,加载凭证
  Future<void> init() async {
    // 读取assets中的三个凭证文件为字节
    final caCert = await rootBundle.load('assets/ca.pem');
    final clientCert = await rootBundle.load('assets/cert.pem');
    final clientKey = await rootBundle.load('assets/key.pem');

    // 创建自定义安全上下文
    SecurityContext securityContext = SecurityContext();
    // 加载CA根证书,对应curl的--cacert参数/requests的verify参数
    securityContext.setTrustedCertificatesBytes(caCert.buffer.asUint8List());
    // 加载客户端证书,对应curl的--cert参数/requests的cert第一个参数
    securityContext.useCertificateChainBytes(clientCert.buffer.asUint8List());
    // 加载客户端私钥,对应curl的--key参数/requests的cert第二个参数
    // 如果私钥设置了密码,需要传入password参数
    securityContext.usePrivateKeyBytes(clientKey.buffer.asUint8List()/*, password: "你的私钥密码"*/);

    // 自定义HttpClient
    HttpClient httpClient = HttpClient(context: securityContext);
    // 如果是用IP访问、证书与域名不匹配,可以放开下面的配置自定义校验逻辑,生产环境不建议直接禁用校验
    // httpClient.badCertificateCallback = (X509Certificate cert, String host, int port) {
    //   return host == '65.0.95.227'; // 仅允许指定IP的证书
    // };

    // 将自定义HttpClient绑定到Dio
    _dio = Dio(BaseOptions(baseUrl: baseUrl));
    (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = () {
      return httpClient;
    };
  }

  // 获取容器列表示例,对应Python示例的接口
  Future<List<dynamic>> getContainerList() async {
    Response response = await _dio.get('/containers/json', queryParameters: {'all': 1});
    return response.data;
  }

  // 打印容器信息示例
  Future<void> printContainersData() async {
    List containers = await getContainerList();
    for (var container in containers) {
      print('Container [Id: ${container['Id']}, Name: ${container['Names'][0]}, Status: ${container['Status']}]');
    }
  }
}

// 调用示例
void main() async {
  DockerApiClient client = DockerApiClient();
  await client.init();
  await client.printContainersData();
}

注意事项

  • 上述方案仅适用于测试环境,生产环境请勿将凭证文件打包在APP assets中,避免凭证泄露,建议通过用户手动上传、服务端动态下发加密存储的方式获取凭证
  • 若使用http包而非dio,逻辑完全一致,直接将自定义SecurityContext传入HttpClient构造方法即可使用
  • 私钥如果有加密,需要在调用usePrivateKeyBytes时传入对应的password参数

内容的提问来源于stack exchange,提问作者mtabishk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 18:36:06