Sharing authentication cookies from browser to http api calls

We have a mobile app (android and ios) created using Ionic 5, Capacitor 1.5 and Angular 9

I am relatively new to using Javascript frameworks and need help understanding how to share cookies with different parts of our application.

If I launch an in app browser window for the user to authenticate against our CAS system - how can I make the authentication cookies from the browser window available to send with the http requests that we make to our API using the HttpClient from ‘@angular/common/http’?

I have tried setting the hostname in the capacitor.config.json file to the same domain as our CAS server and using “withCredentials” in the http api calls but it doesn’t seem to be including the authentication cookies.

I appreciate any suggestions.

4 Likes

I’m facing the same problem. Any tips or best practices?

I’m also trying to find a way to do this.

I’m working with Ionic 5, React 17, and Capacitor 3.

Here’s the flow I’m trying to achieve.

  1. User opens app.
  2. User clicks login button, in-app browser (by Capacitor browser) opens up to a Drupal login page.
  3. Drupal is configured to allow users to log in by registering an email address and password or signing in with their Google or Apple accounts. In all cases, Drupal returns a cookie to the in-app browser.
  4. Somehow, I want to send that cookie back to my app from the in-app browser.

I have the steps up to #3 working.

I know Ionic now has Auth Connect, which looks great but seems to be based on OAuth, not cookies.

Here’s what I’ve tried so far:

  • Using an <iframe> instead of the in-app browser. This is a security issue and Google and Apple both block it.
  • Tried to find a solution for passing the cookie between the in-app browser and the Capacitor app. This medium post suggests it is possible in iOS, but I don’t know enough about coding in Swift to judge how hard this will be to implement.

I struggled with this for quite a long time and unfortunately there’s not an “official” way to do it.

From my research trying to achieve this:

  • The in-app browser is just an instance of chrome/safari
  • Capacitor apps use their own sets of cookies
  • If you auth into an in-app browser it will set cookies for chrome/safari, but not for the app.

While there isn’t a “good” solution, I’ve found that using Cordova’s In App Browser does work, that’s because unlike the Capacitor In-App Browser Cordova’s is a WebView launched by the app.

Personally I would love to see Ionic Portals handling this, but afaik it is not on the roadmap.
@jthoms11 Would this be a use-case to make Ionic Portals available as a Capacitor plugin?

1 Like

Thanks for this info; it’s very helpful.

I just added the Cordova In App Browser plugin, but accessing Google login via OpenID Connect gives me an Error 403: disallowed_useragent saying that my app does not comply with Google’s embedded webview policy. Looks like the policy changed in 2016.

Sign in with Apple does work.

It would be really awesome if Portals could do this.

EDIT: It seems like this may be possible, but I will have to dig into it. I’m a web developer, not an app developer, so it’s hard for me to estimate how much time this will take just looking at the docs.

I’d look into creating an API that you can use to authenticate your app users with. Take a look at JWT’s to help manage your authenticated users in your app.

JWTs can be useful.

But in my case, I don’t want to authenticate users to my app directly. I already have a Drupal server that has its own (cookie-based) authentication system. When signing in from the Drupal website, users can sign in with Google or Apple-- this already works.

So what I want to do is to use my existing infrastructure in my Ionic app.

Cookies are used to remember something in the stateless environment. An app is not stateless.

Assuming your Drupal site has a callback of some type after you login, and you are dead-set on using this approach, I’d suggest some type of event listeners within the app to find out when the URL within the app changes and the capture what the URL is at that point and parse the data.

Again, you won’t store the cookie in the app, you would use some type of local storage to remember what was returned from the Drupal callback.

In my app, Drupal keeps track of all the state. When the user logs in, they get a JSON payload that allows the local state to be cached with react-query, but Drupal is the source of truth.

I have already built the app and, using the capacitor HTTP plugin, I can log in to Drupal using a cookie. The problem is that I can’t sign in with Google/Apple through Drupal in the app, because if I use the capacitor browser plugin, the cookie isn’t passed back to the app. This seems to be a limitation of the capacitor browser, as it makes a separate set of cookies. The cordova in-app browser is discussed above. So I think this question (including the OP) is about the situation of: If you have a web server that you want to authenticate against that uses cookies, and you are accessing that web server via an in app browser, how do you pass the authentication cookie from the in app browser back to the native part of the app?

Let’s say you are able to get the cookie back from the in-app-browser, how are you planning on using it in your app?

The cookie is used whenever the user needs to make an authorized request. For example, updating data, or seeing the user’s private data. With the Capacitor Http plugin, this works really well.

Storing login data in local storage is terrible practice, Httponly cookies literally only exist for auth purposes, that’s what they’re for.

How else would you suggest storing something like a JWT or a refresh token?

Here is a summary of what I am doing to store API tokens - Best way to store Bearer token from API? - #2 by twestrick.

With cookies, that’s the way it should be done both on the web and in-app.