Https网络请求,dio库不走badCertificateCallback回调
来源:1-2 课程导学

慕设计5218244
2024-07-23
1、我使用了dio库,并全局设置了如下代码,进行Https请求,但是不走badCertificateCallback回调,是什么原因?
2、上线的时候需要在badCertificateCallback中判断pem是否正确吗?
HttpOverrides.global = ProxiedHttpOverridesDebug("");
class ProxiedHttpOverridesDebug extends HttpOverrides {
String _proxy;
ProxiedHttpOverridesDebug(this._proxy);
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..findProxy = (uri) {
return _proxy.isNotEmpty ? "PROXY $_proxy;" : 'DIRECT';
}
..badCertificateCallback = (X509Certificate cert, String host, int port) {
if (cert.pem == ThingsboardAppConstants.X509CertificatePem) {
return true;
}
return false;
};
}
}
写回答
1回答
-
CrazyCodeBoy
2024-07-24
在使用 Dio 库进行 HTTPS 请求时,如果你发现 `badCertificateCallback` 回调没有被调用,可能有以下几个原因:
1. **证书有效**:如果你请求的服务器证书是有效的,并且被系统信任的 CA 签署,那么 `badCertificateCallback` 就不会被触发。
2. **请求未到达 HTTPS 证书验证**:如果请求在到达证书验证之前就失败(例如由于网络问题或 DNS 解析错误),则 `badCertificateCallback` 也不会被触发。
3. **设置不正确**:确保你正确设置了 `badCertificateCallback`,并且它确实应用于你的 Dio 实例。
以下是一个正确设置 `badCertificateCallback` 的示例:
```dart
import 'package:dio/dio.dart';
void main() {
final dio = Dio();
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) {
// 在这里处理证书验证
return true; // 始终接受证书(上线时需要更严格的验证)
};
};
// 进行 HTTPS 请求
dio.get('https://example.com').then((response) {
print(response.data);
}).catchError((error) {
print(error);
});
}
```
### 关于上线时的证书验证
在生产环境中,绝对不建议简单地返回 `true` 来跳过证书验证。你应该严格验证证书,以防止中间人攻击等安全问题。以下是一些建议:
1. **校验证书的 PEM**:
在 `badCertificateCallback` 中,对比证书的 PEM 内容是否与预期的一致。
2. **使用安全的 CA**:
确保你的服务器证书是由受信任的 CA 签署的,这样可以避免需要手动验证证书。
3. **定期更新证书**:
确保你定期更新证书,避免证书过期导致请求失败。
示例如下:
```dart
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/services.dart';
import 'package:http/io_client.dart';
import 'package:http/http.dart' as http;
import 'package:http_client_helper/http_client_helper.dart';
void main() async {
final dio = Dio();
// 读取你的证书 PEM 内容
final pem = await rootBundle.loadString('assets/your_cert.pem');
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
final SecurityContext context = SecurityContext();
context.setTrustedCertificatesBytes(utf8.encode(pem));
return HttpClient(context: context)
..badCertificateCallback = (X509Certificate cert, String host, int port) {
// 检查证书是否匹配
return cert.pem == pem;
};
};
// 进行 HTTPS 请求
dio.get('https://example.com').then((response) {
print(response.data);
}).catchError((error) {
print(error);
});
}
```
通过这种方式,你可以确保上线时对证书进行严格的校验,保证请求的安全性。10
相似问题