Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTPS request fails only on iOS, Ionic 2

I have an Ionic 2 application that calls a Spring Boot API to send push notifications to other devices. The API is configured with HTTPS.

The API POST request works on everything except iOS.

My SSL certificate on the server is self signed (maybe that's it?).

Works on:

  • ionic serve
  • Android
  • Postman
  • curl

Here is the request:

public sendNotificationRequest(title: string, action: string, name: string, tokens: any, notifications: boolean) {
    // Check if user turned off notifications
    if(!notifications) {
        return;
    }

    let headers = new Headers({'Content-Type': 'application/json'});
    headers.append('Authorization', 'Basic ' + btoa(this.username_decrypted + ':' + this.password_decrypted));
    let body = this.formObj(tokens, title, action, name);
    console.log(body);

    this.http.post("https://<some-url>",
                    body, { headers: headers }
    ).subscribe((response) => {
        console.log("HTTPS RESPONSE");
        console.log(response);
    }, function(error) {
        console.log("HTTPS ERROR");
        console.log(error);
    });
}

The header responses are as follows:

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");

And the this error is received:

{
 "_body":
    {"isTrusted":true},
    "status":0,"ok":false,
    "statusText":"",
    "headers":{},
    "type":3,
    "url":null
}

Spring Boot API:

@CrossOrigin
@RequestMapping(value="/notifications", method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE, produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<NotificationParent> sendNotifications(@RequestBody NotificationParent objs) {
    ...
    return new ResponseEntity<NotificationParent>(objs, HttpStatus.OK);
}

I am assuming its an iOS security issue, but I have no idea.

like image 243
theblindprophet Avatar asked Mar 05 '17 17:03

theblindprophet


3 Answers

I had a same problem too. Removing the WkWebView solves the issue.

ionic cordova plugin remove cordova-plugin-wkwebview-engine

More info:

https://forum.ionicframework.com/t/ios10-http-requests-blocked/67663/2?u=profitsventure

After this plugin removed I can make http request via iOS

like image 157
Ferdy Fauzi Avatar answered Dec 27 '22 15:12

Ferdy Fauzi


I think your assumption is correct-- an iOS security issue. In iOS there is something called App Transport Security that disallows, by default, connections over HTTP and connections with self-signed certificates.

You have to add

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

to the Info.plist of your project to allow your self-signed traffic.

See this answer as well as the below links for more info.

http://blog.ionic.io/preparing-for-ios-9/

https://gist.github.com/mlynch/284699d676fe9ed0abfa

https://developer.apple.com/library/prerelease/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

like image 37
Daniel Avatar answered Dec 27 '22 17:12

Daniel


For iOS devices, the default WebViewEngine always uses CORS, to disable it temporarily, add the <preference name="CordovaWebViewEngine" value="CDVUIWebViewEngine" /> to the config.xml. However, the downgrading to UIWebViewEngine has bad performance. Solving it in the server side is the right solution.

The HTTP server should be configured to have the right response to the CORS OPTIONS preflight request. The key point is that the Access-Control-Allow-Headers can not be “*” and should include any custom headers used in your app. Below is my setting that works:

Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, MyCustomHeader

like image 27
Ying Avatar answered Dec 27 '22 15:12

Ying