HTTPS POST requests not working in release build

Hi there, I’m having a lot of trouble trying to make https post requests to an API work in production builds of the app.
The app works perfectly in the debug build.

These are the Ionic and Cordova versions

Ionic:

   ionic (Ionic CLI)  : 4.9.0 (/usr/lib/node_modules/ionic)
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.0

Cordova:

   cordova (Cordova CLI) : 8.1.2 (cordova-lib@8.1.1)
   Cordova Platforms     : android 7.1.4
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.2.5, (and 8 other plugins)

System:

   NodeJS : v11.6.0 (/usr/bin/node)
   npm    : 6.6.0
   OS     : Linux 4.19

The https post requests are made through the Angular http library.

I’ve tested solutions that can be found in the following threads:

The solutions applied were:

http://ivancevich.me/articles/ignoring-invalid-ssl-certificates-on-cordova-android-ios/

Adding CSP to the index.html

<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src *; img-src 'self' data:; style-src 'self'; font-src 'self';">

But with no luck.
The certificate used in the webpage where the API is stored is from Let’s Encrypt, is it compatible?

Am I just missing something here?

2 Likes

Hi,

I have the same issue.
Did you get a solution?

I had to use cordova-plugin-advanced-http and change my code so I could do this.http.setSSLCertMode('nocheck'); until I can get the final certificate so I can do SSL Pinning.
This is how I changed my code.

Angular HTTP:

postData(data, object, type) {
   return new Promise((resolve, reject) => {
     var headers = new Headers();
     headers.append('Access-Control-Allow-Origin' , '*');
     headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
     headers.append('Accept','application/json');
     headers.append('content-type','application/json');
     let options = new RequestOptions({headers:headers});

     this.http.post(url, data, options)
       .subscribe(res => {
         resolve(res.json());
       }, (err) => {
         reject(err);
       });
   });
 }

to

Cordova/Ionic Native HTTP:

postData(data, object, type) {
  return new Promise((resolve, reject) => {
    //Don't check SSL Certificate
    this.http.setSSLCertMode('nocheck');
    this.http.setHeader('*', 'Access-Control-Allow-Origin' , '*');
    this.http.setHeader('*', 'Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
    this.http.setHeader('*', 'Accept','application/json');
    this.http.setHeader('*', 'content-type','application/json');
    //Important to set the data serializer or the request gets rejected
    this.http.setDataSerializer('json');
    this.http.post(url, data, {}).then(res =>{
      resolve(JSON.parse(res.data));
    })
    .catch(err =>{
      reject(err);
    });
  });
}

This allowed the HTTPS POST requests to work in the release build

2 Likes

Thanks a lot, you save me.

Hi,
does it work on iOS too?

However I have the same problem with a Let’s Encrypt certificate and this solution seems only not to check the certificate.
It is just a patch not a solution, I mean the problem perhaps is on the certificate.
Or mai I wrong?

Thank you

cld

I’m running into the same issue when using @import url(“https://fonts.googleapis.com/icon?family=Material+Icons”); seems really weird, anyone has a solution for this?

You are correct, this solution was just a workaround until I could get a final CA certificate.
The plugin has also changed since this answer was written, the new code for me would be:

postData(data, object, type) {
    return new Promise((resolve, reject) => {
        // disable SSL cert checking, only meant for testing purposes, do NOT use in production!
        this.http.setServerTrustMode('nocheck', function () {
            console.log('success!');
        }, function () {
            console.log('error :(');
        });
        this.http.setHeader('*', 'Access-Control-Allow-Origin', '*');
        this.http.setHeader('*', 'Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
        this.http.setHeader('*', 'Accept', 'application/json');
        this.http.setHeader('*', 'content-type', 'application/json');
        //Important to set the data serializer or the request gets rejected
        this.http.setDataSerializer('json');
        this.http.post(url, data, {}).then(res => {
            resolve(JSON.parse(res.data));
        })
            .catch(err => {
                reject(err);
            });
    });
}

If you wanted to allow SSL Pinning, which could solve all the problems related to SSL provided you don’t have a self-signed one, the code would be this instead:

// enable SSL pinning
this.http.setServerTrustMode('pinned', function() {
  console.log('success!');
}, function() {
  console.log('error :(');
});

You have to include your certificate in www/certificates. The certificate must have a .cer extension and it must be DER encoded. If it’s PEM encoded you can use this Stack Overflow Answer to convert it to DER.

Source: https://github.com/silkimen/cordova-plugin-advanced-http

Hi,
In my case, the problem was on the server.
The full chain was needed.
This is the solution I’ve found:

1 Like

This is the solution. Thanks a bunch. Spent a few hours on this with no success, this save my life!! :slight_smile:

Hi,

In which file do we need to change this?

I have a similar problem to this but only on Android 9.0.
It’s working fine in ionic cordova run android --device . but not on ionic cordova build android --prod --release . And the server already running under SSL.
https://www.ssllabs.com/ssltest/analyze.html?d=apps.uib.ac.id

Please help me, Thanks