Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sharing cookies between HTTP-Plugin, WKWebView and InAppBrowser #330

Closed
maciej-zabielski opened this issue May 5, 2020 · 14 comments
Closed
Labels

Comments

@maciej-zabielski
Copy link

maciej-zabielski commented May 5, 2020

Hi, I'm trying to solve the following problem that I think is quite typical for many developers?

My app loads in main WebView (based on cordova-plugin-ionic-webview). It tries to make a call to server using this HTTP-Plugin as regular XHR would be blocked due to CORS restrictions.

When it gets Unauthorised response it will open up InAppBrowser (cordova-plugin-inappbrowser - WKWebView based as well) to show user login options (login must support ADFS redirects etc, so easy login via XHR/Basic is not an option here). I know the login will return proper cookies to InAppBrowser WebView - I can see them in Safari console. Cookies will be marked as secure/httpOnly.

After login the InAppBrowser is closed and the app will make another attempt to load data via HTTP-Plugin. Unfortunately something goes wrong here, as the session cookies are not accepted.

Also main WebView should be able to make plane GET requests, e.g. for image resources (non-xhr). Although, the main WebView will have different domain than InAppBrowser ("real" domain vs localhost app).

Should these cookies be theoretically shared between all these instances?
Form Cordova-WkWebView docs: "This plugin creates a shared WKProcessPool which ensures the cookie sharing happens correctly across WKWebView instances. CDVWKProcessPoolFactory class can be used to obtain the shared WKProcessPool instance if app creates WKWebView outside of this plugin."

Since WKWebView plugin implementation can use shared cookie storage for both main WebView and InAppBrowser, it should also be possible for HTTP-Plugin to access the same pool. As a result we could:

  • Authenticate in InAppBrowser using whatever method is needed, including ADFS/SAML
  • Access authentication cookies in main WebView for GET, non XHR requests
  • Use HTTP-Plugin to make all XHR requests to bypass CORS restrictions imposed by WKWebView.

I'm not sure if this is the case for Ionic version as well? I have zero knowledge on iOS native development so that makes things a bit harder :( Similar approach (without HTTP plugin) worked just fine with UIWebView that did not restrict cookie or XHR/CORS.

I would greatly appreciate some feedback from anyone who managed to run that kind of scenario!

@maciej-zabielski maciej-zabielski changed the title Sharing cookies between Plugin, WKWebView and InAppBrowser Sharing cookies between HTTP-Plugin, WKWebView and InAppBrowser May 5, 2020
@maciej-zabielski
Copy link
Author

maciej-zabielski commented May 6, 2020

Some follow up on this - I know a similar question was answered in a discussion here. asked by @varunkumarm. @silkimen replied:

You can't use this plugin to extract the cookies you've received in InAppBrowser, because it's using an own web context which has nothing to do with this plugin.

[EDIT 05.11.2020]
I have removed my original follow up as it was not entirely true, so I will spare the read and try to post our final solution afterwards. I believe we will eventually change the authentication method for mobile app so that it does not require server session and rememberMe cookies.

What I have found out until now (all XHR requests made with HTTP plugin):

  1. After authentication (web page, not XHR) in WKWEbView (InAppBrowser) cookies are not available to XHR, but...
  2. After reloading the browser app (not entire native app) the cookies get synced to underlying native cookie store and at this stage, XHR request will get the rememberMe cookie added automatically!
  3. For the reason I do not understand, only rememberMe cookie (HttpOnly, Secure, with exp. date) is added automatically, but our session cookie is not (HttpOnly, Secure, Session exp).
  4. Now the built in cookie management in HTTP plugin gets in a way, as it will store cookies received in it's local storage and not the shared native store.
  5. Having a session/cookie based authentication this creates a havoc, as we now have one session running in XHR and another one in WebView.
  6. When we log out using InAppBrowser, of course its session is "logged out" but also the "DeleteMe" command will be executed and XHR will loose its "rememberMe" cookie. So this is another example where we can clearly see that they use common cookie store.

If only the session cookie would be added it would work pretty well. At the same time, if in further requests XHR would "restore" session based on rememberMe, it would have to make it available for the WebView do that requests made directly from there also get the proper session.
I still don't understand how WebView and XHR have one common cookie and one "individual" (session cookie). I would have to debug native code to see what cookies are available there at every stage.

@ikosta
Copy link
Contributor

ikosta commented Jun 2, 2020

@silkimen is here any update or comment from your end on this?

@maciej-zabielski
Copy link
Author

I can only add that I haven't abandoned this topic, but having all the problems listed above I have released an app update that is still using UIWebView. I will have to work on a new version before end of year that will most likely include a different session management that is not so heavily dependent on cookies (JWT?), but that requires broad server side changes.

@silkimen
Copy link
Owner

silkimen commented Jun 3, 2020

Hi guys,
I don't know how XHR and InAppBrowser share their cookie stores, but this plugin does not share its cookie store with them. This plugin uses tough-cookie (See README) for cookie management and stores them in the local storage.

But @maciej-zabielski already mentioned this here:

  1. Now the built in cookie management in HTTP plugin gets in a way, as it will store cookies received in it's local storage and not the shared native store.

We had a similar issue in one of our projects at work. We've used an InAppBrowser fork which adds a getter function to access the cookies. You can use setCookie() to copy the cookies into this plugin's cookie storage afterwards.

But unfortunately, there are 1.8k forks of InAppBrowser and I can't remember which fork it was.

@ikosta
Copy link
Contributor

ikosta commented Jun 4, 2020

Hi guys,
I've fixed this with an own plugin to get the cookies from the InAppBrowser and add the into the HTTP-Plugin. Will bullet-proof the plugin and post here when it is release. Works on iOS11+ with WkWebView and Android.

@maciej-zabielski
Copy link
Author

There must be some cookie sharing that happens on underlying connection that HTTP-plugin is using. Even if its not explicit, but as I have mentioned, we get two cookies returned to the InAppBrowser. Session cookie and RememberMe. RememberMe is "taken over" by HTTP-plugin. Even if there is nothing in the localstorage used by plugin, the cookie will be added. I don't understand how session cookie is kept "secret" by the native code. They are basically the same.

On the server side I can see two sessions one that comes from InApp and one from XHR plugin.
When InApp gets rememberMe cookie, after reload of the app, the XHR session will also start sending the same rememberMe cookie. So it must have been taken over from some shared storage (I'm not saying it was done explicitly by the plugin). But I might be delusional here :)

@ikosta it's interesting to see if it will be possible to implement solid "cookie-sync" using your extra plugin. With session cookies it's also important that we can clear them when logout happens. So we should make sure that everything gets removed from underlying native layer and from localstorage.

@silkimen
Copy link
Owner

silkimen commented Jun 4, 2020

@ikosta that's very interesting. When I started developing this plugin (it was a fork that diverged long time ago), I wanted to implement cookie handling in the native code. But the problem (back then) was that I kept loosing cookie data on iOS. Then I decided to use tough-cookie and implement cookie handling in the JS runtime, which made it also easier to develop features for both platforms and it just worked.
Now, that's long time ago and people are using WKWebview instead of UIWebView. Maybe we can integrate your plugin into this plugin?

@nooblado
Copy link

Hi @ikosta,

¿Is your cordova-plugin-cookies working even it's not released? I need a solution like that in my current project, so I can help to test it and give you feedback.

Thank you in advance

Hi guys,
I've fixed this with an own plugin to get the cookies from the InAppBrowser and add the into the HTTP-Plugin. Will bullet-proof the plugin and post here when it is release. Works on iOS11+ with WkWebView and Android.

@ikosta
Copy link
Contributor

ikosta commented Jun 20, 2020

@nooblado yes it is. Had to release an app with first bugfix Version so I had no time to release the plugin. Will update the readme and release it later today.

@ikosta
Copy link
Contributor

ikosta commented Jun 20, 2020

@silkimen an implementation of an unified cookie-store for webview/http-plugin would be very nice but it’s also an edge-case. In our apps we use plenty of external crm api’s with multiple connection settings and from only three of them we need the cookie. One can be taken care of with just the http-plugin and for the other two we need that solution.

@ikosta
Copy link
Contributor

ikosta commented Jun 20, 2020

@nooblado @maciej-zabielski @silkimen I just published the plugin cordova-plugin-cookies

@nooblado
Copy link

Thank you @ikosta! I'm going to add your plugin to my app. Great job!!

@silkimen
Copy link
Owner

Thanks @ikosta, I'll add this into the FAQ list 👍

@silkimen
Copy link
Owner

Closing this, feel free to open a new issue, if this won't solve your problem! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants