Capacitor iOS / Cookie Authentication / capacitor/http

I was able to get cookie authentication with capacitor and capacitor/http to work on my iOS app.

My backend sends a Set-Cookie HTTP Header with a httpOnly Cookie which is used for subsequent requests, even when I close and reopen my app.

As far as I understand this cookie won’t be affected by the Apple ITP because using capacitor/http it now should be a first party cookie.

I’m wondering if that’s correct and if I can rely on capacitor/ iOS on storing the cookie for it’s lifetime (Max-Age) or if there is a mechanism in iOS which removes the cookie after a while?

I would say it’s not recommended to rely on Cookies. It is not guaranteed that iOS and Android will keep them around. We use a Bearer token stored in Preferences with great success. See Best way to store Bearer token from API? - #2 by twestrick.

The most recent conversation about this is over here where a Capacitor team member says don’t use them for native :slight_smile: - Cookies vs. Preferences - what is more persistent?.

Overall, if you search this forum for posts about cookies, there are a ton with people having problems.

Thanks foryour answer!

I would say it’s not recommended to rely on Cookies. It is not guaranteed that iOS and Android will keep them around.

I read this multiple times but after reading a lot of forum posts/ stackoverflow etc. it looks more like an opinion, not like an actual fact. What I found is that cookies set using document.cookie and 3rd party cookies are restricted to a 7-day life-time on iOS due to Apple’s ITP https://documentation.mapp.com/1.0/en/intelligent-tracking-prevention-itp-2-1-7239974.html - that totally makes sense…

When using capacitor/http my understanding is that you get the cookies from your “own” API as first party cookies because capacitor/http proxies all the fetch/ XMLHttpRequests through native code which then also stores the cookie in the native cookie store and also uses the cookies from there for subsequent requests.

The code from capacitor/http sets the cookies to HTTPCookieStorage.

    public func setCookie(_ domain: String, _ action: String) {
        let url = getServerUrl(domain)!
        let jar = HTTPCookieStorage.shared
        let field = ["Set-Cookie": action]
        let cookies = HTTPCookie.cookies(withResponseHeaderFields: field, for: url)
        jar.setCookies(cookies, for: url, mainDocumentURL: nil)
        syncCookiesToWebView()
    }

Until now I couldn’t find anything in Apple’s docs that this cookie storage or single cookies get deleted at any time. That may be the case but other devs having problems with cookies is no real proof that it’s like that as you can do a lot of things wrong with them, leaving iOS out of the equation.

The most recent conversation about this is over here where a Capacitor team member says don’t use them for native :slight_smile: - Cookies vs. Preferences - what is more persistent?.

The post/ the answer from the ionic team member makes absolutely no sense to me - why implement a native bridge for cookies and http when you can’t and shouldn’t use it?

Edit: He just said for storing “data” you shouldn’t use Capacitor Cookies - fine - but what about storing actual cookies? @dallas maybe you can help here?

Overall, if you search this forum for posts about cookies, there are a ton with people having problems

Right, but oftentimes it’s problems with the cookie itself where they can’t get it to work in the first place. Maybe I need to ask this at some iOS dev forum to get a link to some apple doc which states that cookies get deleted after xyz time or under which circumstances…

Your points make sense to me! I was under the impression the Capacitor Cookie plugin was created to fix all the issues people were having but then Dallas’ comment that they are “only intended to be used to work with web systems” totally through me off.

I think you might be right to ask in the iOS forums to determine the lifecycle of HTTPCookieStorage as it isn’t apparent by looking at the documentation.

Hello! We’re currently migrating to Capacitor and are hoping to ditch tokens altogether for cookie auth. I am very much hoping the Capacitor cookie plugin will let us do this. How did it work out for you after this post?

There is this recent post from Dallas (a Capacitor team member) saying Cookies should only be used for web - Cookies vs. Preferences - what is more persistent? - #4 by dallas

I think using something other than Cookies is still more reliable for a native app?

:wave: Yeah! I still strongly recommend not relying on cookies for mobile apps if you can avoid it. Cookies are a uniquely web concept, and they just happen to be much more accessible and reached for here because we work with web technology on mobile. The cookies plugin should be viewed as a compatibility tool. If it works, great! But my recommendation continues to be to rely on tokens and not cookies. :v:

1 Like

Unfortunately due to deadlines and stuff I had to go the token way. I still couldn’t get a real answer why cookies shouldn’t be used.

Technically they work with the http plugin but somehow nobody knows or wants to give a real answer if there is some mechanism in iOS which clears the cookie at some point in time (I doubt it but didn’t want to wait for it ;-))

@dallas Don’t we use web technology (WKWebview on iOS) with capacitor? And why have a “first party” http plugin if the functionality it provides shouldn’t be used?

:wave: Thanks so much! One follow-up question. The Capacitor plugin states:

The Capacitor Cookies API provides native cookie support via patching document.cookie to use native libraries. It also provides methods for modifying cookies at a specific url. This plugin is bundled with @capacitor/core.

So my initial thought is that Capacitor is intercepting and storing cookies natively, a layer higher than the web environment. That makes me initially think that using cookies would be ironclad (even for an HttpOnly cookie). But I’m probably mistaken about something?

The TL;DR, is that these plugins exist to help developers work with existing systems that don’t play nicely with mobile apps, and so when devs ask which to use, I really recommend using mechanisms that are built with native apps in mind (ex, tokens from the OAuth spec instead of using cookies).

The more detailed answer focuses on two pain points that developers pretty consistently run into that are specific to our case.

  1. CORS - CORS can cause all sorts of issues, but in “true native” development, CORS doesn’t exist. This can cause problems for Capacitor devs because they can be working with services that don’t account for CORS. Capacitor HTTP exists so that HTTP traffic can be proxied through the native layer to bypass this CORS restriction that only exists because we’re running in a web browser. If CORS isn’t a problem (because servers are configured properly, or you’re only communicating with your own server, as some examples) you probably don’t need and shouldn’t enable Capacitor HTTP plugin. It’s just additional overhead and complexity that brings no benefit.
  2. Cookies - Many web services that developers want to use rely on cookies. Cookies are a standard part of the web, but they are pretty non-existent as a concept for native mobile apps. As such, trying to implement anything cookie related can cause weird and unexpected issues. The cookies plugin was built to help solve for those specific cases by managing cookies in “native land” and which also necessitates enabling and using Capacitor HTTP, so the native layer can add/receive cookies from requests. This means all your requests now go through native, which is more overhead, makes your http requests more difficult to debug, etc.

Enabling these plugins can fix certain problems that can be complete blockers for devs, but they also bring baggage with them. So if you’re in a position to choose what to use, I’d always suggest the simpler solutions that “just work” over using tools built for compatibility reasons.

2 Likes

Thanks so much! That’s a great point about the additional layer/complexity you’d be adding for all network requests if you turn on the cookies plugin.