Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error on http requests from ionic iOS native to WP rest API (works on web view and DevApp)

We are trying to issue http requests from our ionic app to a Wordpress server (REST API) and get the following error: {"_body":{"isTrusted":true},"status":0,"ok":false,"statusText":"","headers":{},"type":3,"url":null}.

The requests are working fine when we use the web view or ionic DevApp and are failing on iOS devices.

What we did so far:

  • We verified the requests work fine through the DevApp and the web view.
  • We relaxed the cordova whitelist plugin (see our config.xml below).
  • We verified CORS are enabled on our servers (see curl CORS check below)
  • We checked there is no CORS preflight request issued from the iOS device when the request is blocked as we can see the GET request and no OPTIONS request on the server access log.
  • Obviously there is connectivity from the device to the server as we can see the GET request.

If you have any suggestions, even if seem far fetched, we would very much like to hear them.

Thanks for the help!

requesting code

import { Http, Response } from '@angular/http';

...

private requestData(path: String, params:Object = {}){
  return this.http.get( this.request.url + path, {
    params: {
      'consumer_key': this.conf.comm.appId,
      'consumer_secret': this.conf.comm.appSecret
    }
  })
  .map( (res: Response) => this.prepareResponse(res) )
  .catch( (res: Response) => this.catchError(res) );
}

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="app.c***r.***" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>***</name>
    <description>The ***</description>
    <author email="admin@c***r.app" href="https://c***r.app">***</author>
    <content src="index.html" />
    <access origin="*" />
    <access origin="*" subdomains="true" />
    <allow-navigation href="http://*/*" />
    <allow-navigation href="https://*/*" />
    <allow-navigation href="localhost:8080" />
    <allow-navigation href="data:*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="mailto:*" />
    <preference name="ScrollEnabled" value="false" />
    <preference name="android-minSdkVersion" value="19" />
    <preference name="BackupWebStorage" value="none" />
    <preference name="SplashMaintainAspectRatio" value="true" />
    <preference name="FadeSplashScreenDuration" value="300" />
    <preference name="SplashShowOnlyFirstTime" value="false" />
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="3000" />
    <platform name="android">
        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
        ...
        <splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
    </platform>
    <platform name="ios">
        <icon height="57" src="resources/ios/icon/icon.png" width="57" />
        ...
        <splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
    </platform>
    <plugin name="cordova-plugin-whitelist" spec="1.3.3" />
    <plugin name="cordova-plugin-statusbar" spec="2.4.2" />
    <plugin name="cordova-plugin-device" spec="2.0.2" />
    <plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
    <plugin name="cordova-plugin-ionic-webview" spec="^3.0.0" />
    <plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
    <plugin name="cordova-sqlite-storage" spec="3.2.0" />
    <engine name="ios" spec="~4.5.5" />
    <engine name="android" spec="~7.1.4" />
</widget>

curl CORS check

* Hostname was NOT found in DNS cache
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 18.224.***.***...
* Connected to p***r.app (18.224.***.***) port 443 (#0)
* successfully set certificate verify locations:
...
*        SSL certificate verify ok.
> GET /wp-json/wc/v2/products/categories?consumer_key=ck_3***2&consumer_secret=cs_0***b&per_page=100 HTTP/1.1
> User-Agent: curl/7.38.0
> Host: p***r.app
> Accept: */*
> Origin: http://localhost:8080
>
< HTTP/1.1 200 OK
< Date: Fri, 12 Apr 2019 14:44:43 GMT
* Server Apache is not blacklisted
< Server: Apache
< X-Powered-By: PHP/7.0.31
< X-Robots-Tag: noindex
< Link: <https://p***r.app/wp-json/>; rel="https://api.w.org/"
< X-Content-Type-Options: nosniff
< Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
< Access-Control-Allow-Headers: Authorization, Content-Type
< X-WP-Total: 98
< X-WP-TotalPages: 1
< Cache-Control: public, max-age=2592000
< Allow: GET
< Access-Control-Allow-Origin: http://localhost:8080
< Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
< Access-Control-Allow-Credentials: true
< Vary: Origin
< X-Frame-Options: SAMEORIGIN
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=UTF-8
<
like image 923
mikelin Avatar asked Dec 05 '22 10:12

mikelin


2 Answers

The problem was caused by ionic sending ionic://localhost as the origin when used as a compiled app. WP REST responds through rest_send_cors_headers, which passes the origin through esc_url_raw and rejects the url due to its protocol.

To fix this just add the protocol ionic to the allowed protocols list through the filter kses_allowed_protocols.

BTW, if you're from ionic and reading this, consider making the compiled apps behave as close as possible to the web view and DevApp, including origins sent to the servers.

like image 155
mikelin Avatar answered Dec 28 '22 10:12

mikelin


Here’s the code I used after seeing the helpful answers above. Posting in case others are looking for the same solution. This can go in functions.php in your theme or wherever’s convenient.

add_filter('kses_allowed_protocols', function($protocols) {
    $protocols[] = 'ionic';
    return $protocols;
});
like image 31
gorlif Avatar answered Dec 28 '22 10:12

gorlif