Note: I fully acknowledge there may be something I'm missing in the picture, which is part of my reason for posting. I'd like to get the opinion of people more experienced than I am on authN/Z related implementations.
Here's where I am stuck on this whole "no refresh tokens on client apps":
The assumption I make is that without a refresh token, we also can't, for user experience reasons, always have a very short-lived access token, i.e. if we had an access token expiring every 15 minutes with no chance of refreshing we'd have to login again every 15 minutes.
My problem: by extending the lifetime of the access token we're giving a potential MIDM attacker a much more dangerous weapon, i.e. a token that gives access to the resources that could last days, or even forever (as I've seen in far too many projects).
To me, the simplest way to resolve such a situation is a refresh token, even one that sits on the front-end, because to my mind that still beats a long lasting ACCESS token.
This refresh token could be:
- Also a JWT that expires, but maybe expires in a week or so
- A "use only once" token that gets used to refresh the access token and then gets then replaced by a new refresh token
To my eyes, this approach vs. the long lived access token solves a few problems:
- with this approach, I get to keep a short lived access token, so if it falls into bad hands it can't be used for long
if you think the refresh token is even worse, I disagree, because there's two things that make it better:
- once the main user refreshes his token again that previous refresh token won't be usable anymore
- if we assume someone steals our refresh token WHILE we're browsing, in a matter of minutes our browser would try to use that refresh token, fail (because someone else used it and so it's no longer usable) and prompt us to login, which will again completely invalidate the other series of refresh token obtained by the malicious entity
- even if 1 and 2 weren't true in all scenarios (i'm thinking multiple sessions/refresh tokens allowed so not a single stack or refresh tokens but multiple) i would still wager that you're better off invalidating refresh tokens through whatever procedure you want than you are invalidating access tokens. a JWT access token is valid in itself and the entire purpose of using one is that you can trust it by just verifying it, without having to do other expensive operations like checking with the auth server if it's blacklisted or not. That would essentially mean having to check this sort of thing for EVERY request EVER done with EVERY access token = not very scalable, especially if you compare this to just having to do this sort of thing ONCE every 15 minutes for the refresh token (you could keep a refresh tokens blacklist).
So, with all this said, is having a client side "use once" refresh token that also is a JWT and expires that unreasonable? We're avoiding having the access token last weeks, how can that be bad?