Flutter web,向具有自签名证书的服务器发出请求时出现问题

Flutter web, problem making request to a server with self signed certificate

我遇到了 Flutter Web 的第一个大问题。

我必须通过对具有自签名 ssl 证书的服务器的 post 调用来使用 oauth2 登录。

使用 http 和 dio 客户端发出请求,我收到 net::ERR_CERT_AUTHORITY_INVALID。我在网上找到的唯一方法是使用 HttpClient,它适用于 android 和 IOs,但 dart:io 在 Web 构建中不起作用。 有没有办法信任我的 flutter web ssl 证书?

       // My simple line of code
      var response = await client.post(authorizationEndpoint.toString(), body: body, headers: headers);
      // What I am looking for 
      var response = await client.post(authorizationEndpoint.toString(), 
                               body: body, headers: headers, 
                       --->    trustanyCA: true);

您可以使用 https://pub.dev/packages/universal_io 包。除了 Android 和 iOS.

之外,它还支持网络
dependencies:
  universal_io: ^1.0.1

执行以下导入而不是 dart:io

import 'package:universal_io/io.dart';

原理相同。

import 'package:universal_io/io.dart';

Future<void> main() async {
  final request = HttpClient().getUrl(Uri.parse('https://example.com/path'));

  if (request is BrowserHttpClientRequest) {
    request.credentialsMode = BrowserHttpClientCredentialsMode.include;
  }

  final response = await request.close();
  // ...
}

编辑:

试试这个,因为它似乎不适用于 String,请尝试使用 Bytes 方法并遵循证书路径。

ByteData data = await rootBundle.load('assets/raw/certificate.crt');
SecurityContext context = SecurityContext.defaultContext;
context.setTrustedCertificatesBytes(data.buffer.asUint8List());
client = HttpClient(context: context);

编辑 2:

如果你用HttpClient.badCertificateCallback会怎样
这是接受任何证书的代码:

_client = new HttpClient();
_client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;

编辑 3:

class MyHttpOverrides extends HttpOverrides{
  @override
  HttpClient createHttpClient(SecurityContext context){
    return super.createHttpClient(context)
      ..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;
  }
}

void main(){
    HttpOverrides.global = new MyHttpOverrides();
    runApp(new MyApp());
}

网络版无法做到这一点。浏览器的 XMLHttpRequest 不允许绕过不受信任的证书,但可以通过其他 http 客户端做到这一点。

如果仅用于调试目的,您可以尝试将 SSL 证书添加到系统的受信任证书中(对于 macOS,将其放到 系统证书 Keychain Access),以及覆盖浏览器的安全选项。请参阅 this question 了解如何在 Chrome 中覆盖它。

对于生产用途,您仍然需要一个受信任的有效证书。

如果您使用自签名证书进行开发和测试,您可以将您的操作系统设置为始终信任该证书,浏览器将遵守这一点。

或者,您可以使用 Let's Encrypt 生成有效证书,然后让本地网络服务器使用它。

最后 - 如果您想要一个快速简单的解决方案,ngrok 将为您提供一个通往本地主机的安全隧道,您可以将其用于开发和测试。

此外,如果您使用的是 google chrome,请转到您的本地主机站点设置并将不安全内容从阻止更改为允许可能会有所帮助。