我正在Dart中发送发帖请求。当我在Postman等API测试工具上进行测试时,它会给出响应。但是当我运行该应用程序时。它给了我以下错误:-
E/flutter ( 6264): HandshakeException: Handshake error in client (OS Error: E/flutter ( 6264): CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:363))
这是我的函数代码-
未来getAccessToken(String url)异步{
try {
http.post('url',
body: {
"email": "xyz@xyz.com",
"password": "1234"
}).then((response) {
print("Reponse status : ${response.statusCode}");
print("Response body : ${response.body}");
var myresponse = jsonDecode(response.body);
String token = myresponse["token"];
});
} catch (e) {
print(e.toString());
}
这是完整的错误正文-
E/flutter ( 6264): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception: E/flutter ( 6264): HandshakeException: Handshake error in client (OS Error: E/flutter ( 6264): CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:363)) E/flutter ( 6264): #0 IOClient.send (package:http/src/io_client.dart:33:23) E/flutter ( 6264): <asynchronous suspension> E/flutter ( 6264): #1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:169:38) E/flutter ( 6264): <asynchronous suspension> E/flutter ( 6264): #2 BaseClient.post (package:http/src/base_client.dart:54:7) E/flutter ( 6264): #3 post.<anonymous closure> (package:http/http.dart:70:16) E/flutter ( 6264): #4 _withClient (package:http/http.dart:166:20) E/flutter ( 6264): <asynchronous suspension> E/flutter ( 6264): #5 post (package:http/http.dart:69:5) E/flutter ( 6264): #6
_MyLoginFormState.getAccessToken (package:chart/main.dart:74:7) E/flutter ( 6264): <asynchronous suspension> E/flutter ( 6264): #7
_MyLoginFormState.build.<anonymous closure> (package:chart/main.dart:64:29)
答案 0 :(得分:22)
为了清楚起见,尤其是为了使新手更加顺畅/飞镖,以下是您需要做的事情,以便在您的项目中全局启用此选项:
class MyHttpOverrides extends HttpOverrides{ @override HttpClient createHttpClient(SecurityContext context){ return super.createHttpClient(context) ..badCertificateCallback = (X509Certificate cert, String host, int port)=> true; } }
HttpOverrides.global =新的MyHttpOverrides();
This评论对于解决此问题非常有帮助
答案 1 :(得分:10)
如果您使用的是Dio library,请执行以下操作:
Dio dio = new Dio();
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(HttpClient client) {
client.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
return client;
};
答案 2 :(得分:7)
此代码对我有用
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(MyApp());
}
我想你也会一样...
答案 3 :(得分:6)
我发现正确的方法(但很糟糕)是允许所有证书。
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
String url ='xyz@xyz.com';
Map map = { "email" : "email" , "password" : "password};
HttpClientRequest request = await client.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(map)));
HttpClientResponse response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);
答案 4 :(得分:6)
import 'package:http/io_client.dart';
import 'dart:io';
import 'package:http/http.dart';
import 'dart:async';
import 'dart:convert';
Future getAccessToken(String url) async {
try {
final ioc = new HttpClient();
ioc.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
final http = new IOClient(ioc);
http.post('url', body: {"email": "xyz@xyz.com", "password": "1234"}).then(
(response) {
print("Reponse status : ${response.statusCode}");
print("Response body : ${response.body}");
var myresponse = jsonDecode(response.body);
String token = myresponse["token"];
});
} catch (e) {
print(e.toString());
}
}
答案 5 :(得分:2)
为了解决问题而不是允许一切而登陆这里的每个人。
对我来说,问题在服务器端解决了(应该是这样),代码没有改变。现在一切都有效。在所有其他解决方案中,问题仍然存在(例如,邮递员运行但它在响应状态旁边的地球上显示配置错误) 配置是Centos/Apache/LetsEncrypt/Python3.8/Django3.1.5/Mod_wsgi/ 但我猜这个解决方案对大多数Apache/LetsEncrypt的安装都有效
解决步骤是
SSLCACertificateFile /etc/httpd/conf/ssl.crt/my_ca.crt
参考资料: https://access.redhat.com/solutions/43575 https://letsencrypt.org/certs
您也可以在 https://www.digicert.com/help/ 中检查证书的有效性。
答案 6 :(得分:2)
这个问题发生在我们身上,因为我们没有使用在 nginx 上使用 let's encrypt 生成的 fullchain.pem。更改后即可解决此问题。
server {
listen 443 ssl;
ssl_certificate /var/www/letsencrypt/fullchain.pem;
对于 Apache,您可能需要配置 SSLCertificateChainFile
。关于问题的更多讨论 https://github.com/flutter/flutter/issues/50699
答案 7 :(得分:2)
在设备设置中检查设备日期和时间。设备日期和时间设置为上一个日期。
答案 8 :(得分:1)
我特别需要使用lib/client.dart
Client
接口进行http调用(即http.Client而不是HttpClient)。 ChopperClient
(link)要求这样做。
因此,我无法将HttpClient
的{{1}}直接传递给Chopper。
ChopperClient可以在lib/_http/http.dart
中包装的构造函数中接收HttpClient
。
ioclient.IOClient
这样,您可以暂时忽略通话中的CERTIFICATE_VERIFY_FAILED错误。请记住-仅用于开发目的。不要在生产环境中使用它!
答案 9 :(得分:1)
(我认为)最好的方法是为受信任的主机允许证书,因此,如果您的API主机为"api.my_app"
,则只能允许来自此主机的证书:
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) {
final isValidHost = host == "api.my_app";
return isValidHost;
});
如果您有更多主机,则可以在其中添加新的支票。
答案 10 :(得分:1)
对我来说,这是因为我使用的是 HTTPS,而 API 使用的是 HTTP,所以我只是将其更改为 HTTP 并且可以正常工作。
答案 11 :(得分:1)
实际上,就我而言,它在我更新电脑上的日期和时间后修复了我。我猜可能会帮助某人
答案 12 :(得分:0)
使用tls 1.3
请求URL,没问题。
例子
import 'dart:io';
main() async {
HttpClient client = new HttpClient();
// tls 1.2 error
// var request = await client.getUrl(Uri.parse('https://shop.io.mi-img.com/app/shop/img?id=shop_88f929c5731967cbc8339cfae1f5f0ec.jpeg'));
// tls 1.3 normal
var request = await client.getUrl(Uri.parse('https://ae01.alicdn.com/kf/Ud7cd28ffdf6e475c8dc382380d5d1976o.jpg'));
var response = await request.close();
print(response.headers);
client.close(force: true);
}
答案 13 :(得分:0)
使用 Dio package 在我的本地服务器上使用自签名证书进行请求,我更喜欢允许特定主机而不是所有域。
//import 'package:get/get.dart' hide Response; //<-- if you use get package
import 'package:dio/dio.dart';
void main(){
HttpOverrides.global = new MyHttpOverrides();
runApp(MyApp());
}
class MyHttpOverrides extends HttpOverrides{
@override
HttpClient createHttpClient(SecurityContext context){
return super.createHttpClient(context)
..badCertificateCallback = ((X509Certificate cert, String host, int port) {
final isValidHost = ["192.168.1.67"].contains(host); // <-- allow only hosts in array
return isValidHost;
});
}
}
// more example: https://github.com/flutterchina/dio/tree/master/example
void getHttp() async {
Dio dio = new Dio();
Response response;
response = await dio.get("https://192.168.1.67");
print(response.data);
}
答案 14 :(得分:0)
好吧,我发现问题的真正根源是测试设备上的时钟不同步...
答案 15 :(得分:-2)
通常,当您无法使用外部程序包时会发生此问题,而当您的PC中有严格的防火墙设置时,就会发生此问题。大多数情况下,当您使用公司提供的PC时,它们会安装特殊程序来阻止这些服务。因此,请禁用它们,并希望它会起作用。