Problem with ionic-appauth on Android device (iOS works ok)

I have an Ionic app (Ionic 6, Capacitor 3, Angular 13) and for Okta authentication I am using the ionic-appauth library. Everything is working ok on my iOS device but when I login on Android I get the error:

Web page not available
The web page at com.oktapreview.myCompany:/callback?code=XXXXXX could not be loaded because:

net::ERR_UNKNOWN_URL_SCHEME

I have no idea whether this is to do with the settings I have in my app on the Okta dashboard which are:

Okta Domain: com.oktapreview.myCompany

Sign-in redirect URIs: com.oktapreview.myCompany:/callback

Sign-out redirect URIs: com.oktapreview.myCompany:/logout

or something to do with the way I have configured my oidcConfig in my app:

oidcConfig: {
    client_id: 'xxxxx',
    server_host: 'https://myserver/oauth2/default',
    redirect_url: 'com.oktapreview.myCompany:/callback',
    end_session_redirect_url: 'com.oktapreview.myCompany:/logout',
    scopes: 'openid profile',
    pkce: true,
    audience: 'api://default',
  },

or maybe something in my android manifest file? I currently have this:

<intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="com.oktapreview.myCompany"/>
      </intent-filter>
      
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>

Can anyone see anything I might be doing wrong?

It seems like your scheme isn’t being registered in Capacitor. It also seems like you are following the instructions for configuring things. Maybe you can try creating a brand new app (with the Ionic CLI and OktaDev Schematics) and see if that works? If it does, use something like SmartSynchronize to compare the code.

Thanks - I have done just that (created an app using the Schematics) and it works ok in there - I’ve not been able to get it working in my app yet though.

One thing I have noticed is that in our capacitor.config file we have:

server: {
    androidScheme: 'https',
},

is that likely to mess things up with Okta?

Possibly, especially if it’s overriding the one that’s set in AndroidManifest.yml.

I added it to the app that works and it continued to work so I guess it’s not that.

When you say “It seems like your scheme isn’t being registered in Capacitor” what do you mean exactly?

I’ve not got anywhere with this unfortunately :frowning:

I’ve tried comparing the two apps but we have so much more functionality and dependencies in our app I am not really sure what to do. I re-added the schematics to our app from scratch and tried the login and tabs pages but they failed with the same error.

If you can think of anything that might be causing my scheme error to occur in Android please let me know!

I have tracked down the problem.

Our app still makes use of the cordova-plugin-inappbrowser plugin. If I add that to the package.json of the sample application I created with the OktaDev Schematics and then run npm install and re-build it, the app returns exactly the same error I have been getting when you log in.

Does that make any sense to you at all @mraible ? I thought the InAppBrowser plugin had no affect on an app at all unless you specifically use it but simply adding it as a dependency to the app results in the error occuring.

I’m wondering if adding it it affects the way usernames and passwords are stored and pre-filled or something because without the plugin added, when I get to the Okta screen my username is pre-filled ok and I always have to type the password in but when I add the plugin the username is blank (although there is an auto-fill option at the bottom of the screen) and there is an auto-fill for the password - does that make any sense?

I’m glad to hear you figured out the cause of the problem @richardshergold!

OktaDev Schematics only adds the cordova-plugin-inappbrowser for Cordova apps, not for Capacitor.

If it’s a Cordova apps, it adds a whole bunch of plugins. My guess is you might need to add the cordova-plugin-customurlscheme too and configure its URL_SCHEME in your package.json.

If you generate a new Ionic app and install OktaDev Schematics with Cordova, you’ll see the expected syntax.

Thanks @mraible. Unfortunately that doesn’t seem to have made any difference.

Our app is a Capacitor app but still relies on a few older Cordova plugins still (InAppBrowser being one of them).

I added the following into my package.json:

under dependencies:

"cordova-plugin-customurlscheme": "^5.0.2",

under cordova.plugins:

"cordova-plugin-customurlscheme": {
        "URL_SCHEME": "com.oktapreview.myCompany",
        "ANDROID_SCHEME": " ",
        "ANDROID_HOST": " ",
        "ANDROID_PATHPREFIX": "/"
}

(com.oktapreview.myCompany is our okta url)

I then ran npm install and a rebuild.

That has had no effect - I get the original error as soon as I login to Okta. Is there anything else I need to do do you think? If I cannot get this to work my only other option is to remove the InAppBrowser plugin from our app but that will require a lot of additional re-work so my preference would be to try and get this working with it in.

What I don’t understand is that simply having the InAppBrowser installed in the app affects this OktaLogin callback. I’m not telling the app to use the InAppBrowser at this point - simply adding it as a dependency makes the callback fail. Why is that? Does that make sense?

In case I’m not being clear this is what generates the error:

  1. Create an Ionic app.
  2. Install OktaDev Schematics (with default Capacitor option)
  3. Add the InAppBrowser dependency into package.json and run npm install and rebuild the app.

This results in the callback error on Okta Login i.e simply adding the InAppBrowser plugin and not making any reference to it anywhere in the code. This only affects Android. iOS works ok.

My problem is that our app does need to have the InAppBrowser plugin as a dependency (for use elsewhere in the app). I don’t understand why simply having the plugin installed in the app causes this issue?

Solved the issue by altering the library to ignore the cordova browser:

export const browserFactory = (platform: Platform) => {
  //return platform.is('cordova') ? new CordovaBrowser() : new CapacitorBrowser();
  return new CapacitorBrowser();
};

I ran into this same issue today and tried to use the same solution as you. Unfortunately, I get the following error when trying to run with Pixel XL API 31.

2022-05-07 11:17:56.292 5060-5060/io.ionic.starter E/Capacitor/Console: File: http://localhost/vendor.js - Line 69601 - Msg: ERROR Error: Uncaught (in promise): Error: "Browser" plugin is not implemented on android
    Error: "Browser" plugin is not implemented on android
        at createPluginMethod (http://localhost/vendor.js:315:15)
        at http://localhost/vendor.js:324:22
        at _ZoneDelegate.push.3484._ZoneDelegate.invoke (http://localhost/polyfills.js:511:30)
        at Object.onInvoke (http://localhost/vendor.js:88708:33)
        at _ZoneDelegate.push.3484._ZoneDelegate.invoke (http://localhost/polyfills.js:510:56)
        at Zone.push.3484.Zone.run (http://localhost/polyfills.js:271:47)
        at http://localhost/polyfills.js:1428:38
        at _ZoneDelegate.push.3484._ZoneDelegate.invokeTask (http://localhost/polyfills.js:545:35)
        at Object.onInvokeTask (http://localhost/vendor.js:88695:33)
        at _ZoneDelegate.push.3484._ZoneDelegate.invokeTask (http://localhost/polyfills.js:544:64)

Did you see this when you were trying to fix this issue @richardshergold?

Haven’t seen this and we have tested on two Pixels. Seems strange?

Installing @capacitor/browser got me past this. I tried @capacitor-community/http and was able to get rid of Cordova plugins too. Works great on iOS, but not Android.

2022-05-09 14:13:30.745 14937-16415/io.ionic.starter I/System.out: org.json.JSONException: JSValue could not be coerced to JSObject.
2022-05-09 14:13:30.746 14937-16415/io.ionic.starter E/Capacitor/Plugin: JSONException
    org.json.JSONException: JSValue could not be coerced to JSObject.
        at com.getcapacitor.plugin.http.JSValue.toJSObject(JSValue.java:42)
        at com.getcapacitor.plugin.http.CapacitorHttpUrlConnection.setRequestBody(CapacitorHttpUrlConnection.java:193)
        at com.getcapacitor.plugin.http.HttpRequestHandler.request(HttpRequestHandler.java:395)
        at com.getcapacitor.plugin.http.Http$1.run(Http.java:83)
        at java.lang.Thread.run(Thread.java:920)

Tracking in capacitor-community/http#199.