I am sending a post request in Dart. It is giving a response when I test it on API testing tools such as Postman. But when I run the app. It gives me the following error:-
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))
Here is my code of the function -
Future getAccessToken(String url) async {
try {
http.post('url',
body: {
"email": "[email protected]",
"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());
}
Here's the full error body:
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)
In order to enable this option globally in your project, here is what you need to do:
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 comment was very helpful to pass through this matter, and please note that...
This should be used while in development mode, do NOT do this when you want to release to production, the aim of this answer is to make the development a bit easier for you, for production, you need to fix your certificate issue and use it properly, look at the other answers for this as it might be helpful for your case.
Download cert from https://letsencrypt.org/certs/lets-encrypt-r3.pem
Add this file to assets/ca/ Flutter project root directory
Add assets/ca/ assets directory in pubspec.yaml
Add this code on your app initialization:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
ByteData data = await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem');
SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List());
runApp(MyApp());
}
It works with the default chain, so no changes are needed on the server. Android < 7.1.1 clients will still have access in a browser context.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With