Skip to content
This repository was archived by the owner on Sep 26, 2022. It is now read-only.

Can this plugin override all HTTP calls? #45

Closed
mraible opened this issue Aug 17, 2020 · 26 comments
Closed

Can this plugin override all HTTP calls? #45

mraible opened this issue Aug 17, 2020 · 26 comments
Labels
bug Something isn't working

Comments

@mraible
Copy link

mraible commented Aug 17, 2020

Describe the bug

I'm trying to use Okta's Angular SDK and Sign-In Widget to embed a login form in my Ionic + Capacitor application. Everything works fine when I run it in my browser. When I try to run it in iOS Simulator, I get the following error:

Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin.

I've known about this issue in the past and thought adding this plugin would solve the problem. Okta only allows http/s schemes for its Trusted Origins, and they're not (currently) willing to add support for capacitor://.

I tried installing this plugin to fix the problem:

npm install @capacitor-community/http
npx cap sync

Unfortunately, it still happens.

If I run the following command, it does use http://localhost:8100 as the origin instead of capacitor://localhost.

ionic capacitor run ios -l --host=localhost

To Reproduce
Steps to reproduce the behavior:

git clone -b angular-sdk https://github.com/oktadeveloper/okta-ionic-social-login-example
cd okta-ionic-social-login-example
npm i
npm run build
ionic capacitor add ios

Run app in Xcode, click Login, debug with Safari and you'll see the invalid origin error.

Expected behavior

This plugin overrides all origin headers to use http://localhost:8100 rather than capacitor://localhost.

@TomBeckett
Copy link

@mraible Did you happen to get any further with this?

@mraible
Copy link
Author

mraible commented Nov 9, 2020

@TomBeckett I have made progress in convincing Okta that they should support capacitor://localhost as a trusted origin. Unfortunately, our engineering team hasn't committed to a date yet. I'm hoping before the end of the year.

@thomasvidas
Copy link
Contributor

@mraible has Okta added capacitor://localhost as a trusted origin yet? Either way, I'll take a look at the underlying issue with the capacitor:// scheme

@thomasvidas thomasvidas added the bug Something isn't working label Jan 19, 2021
@mraible
Copy link
Author

mraible commented Jan 19, 2021

@thomasvidas We did last week. However, we had to roll it back because the implementation caused all kinds of issues with existing data.

@FelixSchwarzmeier
Copy link
Contributor

@mraible is Okta currently trying to find a new solution/implementation to be able to add capacitor://localhost as a trusted origin or is this on hold at the moment?

@mraible
Copy link
Author

mraible commented Jan 21, 2021 via email

@FelixSchwarzmeier
Copy link
Contributor

@mraible can you already give an ETA for the new solution?

@mraible
Copy link
Author

mraible commented Feb 4, 2021 via email

@FelixSchwarzmeier
Copy link
Contributor

@mraible Okay, thanks for the quick reply!
Have you found another way to get the Okta Sign-In Widget working in a Capacitor application on iOS?

@mraible
Copy link
Author

mraible commented Feb 4, 2021 via email

@FelixSchwarzmeier
Copy link
Contributor

@thomasvidas Have you alrady had the chance to look at the underlying issue with the capacitor:// scheme?

@thomasvidas
Copy link
Contributor

thomasvidas commented Feb 5, 2021

We use capacitor:// in @capacitor/ios because of a previous security issue we had when using http:// in older versions of capacitor. We use that scheme to communicate between the native layer and the webview. Unfortunately Apple prevents us from overriding/extending the http:// scheme, so we can't intercept HTTP calls and that could lead to a mismatch between the native and web layers.

Here is the relevant part of the Apple Docs

It is a programmer error to register a handler for a scheme WebKit already handles, such as https, and this method raises an invalidArgumentException if you try to do so.

Hence why we use capacitor://. I'll be sure to update when I get a chance to dive into this more, but I don't have an answer yet

@FelixSchwarzmeier
Copy link
Contributor

I see, thanks for the detailed explanation!

@FelixSchwarzmeier
Copy link
Contributor

FelixSchwarzmeier commented Feb 10, 2021

@mraible I tried your recommended approach using your OktaDev Schematics project. I can transfer the access- and id-token to my application’s WebView. However, I am currently not able to get any session cookie information that I need to SSO into my applications. Using the Okta Sign-In Widget, I was able to set the Okta session cookie, do you know how I could achieve the same result when redirecting to Okta to login?

@mraible
Copy link
Author

mraible commented Feb 10, 2021

@FelixSchwarzmeier Why do you need a session cookie? You might have better luck asking how to accomplish your use case on the Okta developer forums.

@FelixSchwarzmeier
Copy link
Contributor

@mraible I need a session cookie to Single-Sign-On into my applications. Okay thanks, will create a new topic there.

@FelixSchwarzmeier
Copy link
Contributor

@mraible FYI: I’ve got the Okta Sign-In-Widget working on iOS as well. The Okta Auth JS SDK supports adding your own http request implementation. You can pass the custom implementation via the authParams configuration of the Sign-In-Widget. Using the capacitor http plugin, you can then override the requests as follows which works great for my use case:

widget = new OktaSignInWidget({
  ...
  authParams: {
    httpRequestClient: async function(method, url, args) {
      const { Http } = Plugins;
      const { headers, data } = args;
      const ret = await Http.request({
        method,
        url,
        headers,
        data
      });
      const responseMsg = {
        responseText: JSON.stringify(ret.data),
        status: ret.status
      };
      return Promise.resolve(responseMsg);
    }
  }
});

@mraible
Copy link
Author

mraible commented Mar 11, 2021

It's been a couple of weeks. @FelixSchwarzmeier Is this working well for you?

@FelixSchwarzmeier
Copy link
Contributor

@mraible Yes, it's working well.

@SmartPlugins
Copy link

@FelixSchwarzmeier

Does this fix require the Capacitor-http plugin?

@FelixSchwarzmeier
Copy link
Contributor

@SmartPlugins Yes, it requires the Capacitor http plugin to avoid any CORS issues.

@SmartPlugins
Copy link

@FelixSchwarzmeier
We use Outsystems for the Frontend development that is powered by Cordova.
We were able to pass invoke apis using Cordova HTTP as you detailed about overriding the httpRequestClient.

We now have the following issue:, want to check if that was the case in your implementation too?
Unrecognized Content-Security-Policy directive 'report-to'.
Unable to post message to https://xyz.outsystemscloud.com. Recipient has origin outsystems://xyz.outsystemscloud.com.

@FelixSchwarzmeier
Copy link
Contributor

@SmartPlugins Sorry, I've never encountered this issue.

@mcarriere
Copy link

mcarriere commented Jul 13, 2021

I have the same issue as @SmartPlugins when trying @FelixSchwarzmeier's workaround.

Unrecognized Content-Security-Policy directive 'report-to'.
Unable to post message to http://localhost. Recipient has origin capacitor://localhost.

--- UPDATE ---
Finally figured it out, make sure on ios the redirectUri is capacitor://localhost/something and on android http://localhost/something. You also don't need the http plugin anymore, seems like okta is now allowing capacitor:// in the trusted origins/cors.

Very unrelated to the orignal issue, just figured it might help @SmartPlugins.

@thomasvidas
Copy link
Contributor

Closing this since it seems that Okta is allowing capacitor:// as a trusted origin as well as the open RFC on the Capacitor repo

@phofferkamp
Copy link

@mraible FYI: I’ve got the Okta Sign-In-Widget working on iOS as well. The Okta Auth JS SDK supports adding your own http request implementation. You can pass the custom implementation via the authParams configuration of the Sign-In-Widget. Using the capacitor http plugin, you can then override the requests as follows which works great for my use case:

widget = new OktaSignInWidget({
  ...
  authParams: {
    httpRequestClient: async function(method, url, args) {
      const { Http } = Plugins;
      const { headers, data } = args;
      const ret = await Http.request({
        method,
        url,
        headers,
        data
      });
      const responseMsg = {
        responseText: JSON.stringify(ret.data),
        status: ret.status
      };
      return Promise.resolve(responseMsg);
    }
  }
});

I have created a repo that implements this solution:

https://github.com/phofferkamp/Ionic-Okta-Widget-Starter

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants