I’m personally using Ionic 5 React and Capacitor 2, and soon will upgrade to Capacitor 3. But the relevance of this question isn’t limited to those details.
So far I’ve seen two clusters of recommendations for how to set up authentication.
- I’ve seen some blog posts recommend storing authentication tokens in Ionic Storage and then send them with the Authentication header in HTTP calls made with axios or whatever other browser-based HTTP library you’re using.
I assume the reason the author of that blog post is okay with storing the authentication information in the header is because the token is a JWT with an encrypted signature, so it can’t be modified. However, it could still be copied by a malicious script. Theoretically, storing authentication credentials in Storage isn’t secure, although I’m not sure how significant a concern that is with mobile apps that take reasonable precautions.
- Other people are trying to use HTTP cookies instead. This seems like the more secure approach. However, I also see that there are sometimes issues with using cookies within WebViews (example: 140205 – WKWebView does not provide a way to set cookie accept policy), and it seems people are working around this using capacitor/http, as discussed at Cookie-based authentication for iOS for Ionic React / Capacitor.
I’m posting this topic because I would prefer to avoid spending maybe days implementing one of these methods, and then go through the trouble of launching an app on the App Store / Play Store, only to find that there are obscure bugs with using whatever authentication method I have implemented.
Is there a reliable solution to implementing HTTP cookies for authentication in Ionic projects? Or is the less secure approach of storing authentication tokens in Storage (or SecureStorage) the best approach from a reliability, “it’s definitely going to work” perspective?
Also there are third party solutions that can manage all of this for probably less than the time it is going to take to roll your own. Is this a personal project? A client project?
I wouldn’t agree with the characterization of either cookies or tokens as inherently more or less secure. Here is a fairly comprehensive comparison of the two options that can provide some additional topics for conversation. Some key points from there:
- cookies make the server work harder
- cookies are more of a hassle in mobile environments than tokens are
- tokens tend to be physically bigger
I find it helpful when discussing security issues to focus on specific threat scenarios. You raised one:
Where would this hypothetical malicious script be running? If it’s a rogue app on an otherwise trusted device, I would trust the OS app-from-app firewalling to prevent that. If it’s a man-in-the-middle, then as long as all your communication is done using TLS (HTTPS), also no problem.
There are two primary things I worry about here:
- can blackhat pretend to be my trusted user on my system?
- can blackhat pretend to be my trusted user somewhere else, like their mobile banking app?
2 is the big get-yourself-sued-into-oblivion problem, and the reason why I tell people to never store passphrases in storage. With a token in storage, the worst thing that could happen is #1.
Personally, I would use tokens, simply out of philosophical concerns. HTTP is a stateless protocol, REST inherits that, and tokens fit that philosophy. Cookies try to bolt state on, and I’ve never found that comfortable.
Thanks for pointing out the two very different concerns: a blackhat pretending to be the user on my system versus at their bank. Yes, a token avoids the problem there because the user’s password (which they might also use for banking) would not be stored.
It sounds like there is a solid pragmatic argument for using the “tokens and storage” approach, just because for a typical mobile application the damage that could be done is minimal. The worst that could happen is they might swap out the user’s profile photo or something, not steal their money.
As a follow-up question though, really my original question was about what you said here:
“cookies are more of a hassle in mobile environments than tokens are”
Is capacitor/http still not a 100% solution to making cookies reliable on mobile?
It does seem like WebView browser-based cookies have enough edge cases that just for the sake of saving my time I would probably use a token approach, but perhaps capacitor/http is a reasonable alternative?
Hi Aaron. I’m just trying to understand what the reasonable options are. Basically, what options are expected to work more or less out of the box with few edge cases I need to handle. So far it sounds like cookies are not that.
I am also investigating 3rd party authentication solutions like Firebase, but I’d still like to understand what’s available to me (and reliable) in Ionic, as part of evaluating the various options.
Sadly, I can’t help you there because I ditched cookies years ago. You’re also using React, whereas I really love Angular’s
HttpClient and therefore use it pretty exclusively.
I can say this, though: “can I trust this thing?” is a question that the server needs different sources of information to be able to answer for tokens and cookies. For tokens, all that is needed is contained within the JWT. The server can look at the signature and say “yep, I signed that”, or “no, I didn’t”. Part of the work done by public-key encryption for tokens has to be done out-of-channel for cookies, and that’s where XSRF and CORS start to come into play.
If you asked me to list off the top of my head what the three most common topics on these forums are, I would guess CORS would be in the top three, along with “asynchronous programming is hurting my brain” and “I tried upgrading a bunch of dependencies and now everything’s broken”.
Thanks for your tips guys