In my current architecture, my backend issues a JWT back to the (mobile) client. The primary reason to opt for a JWT is stateless authentication, i.e. the server doesn't need to store data in the session/database, which means less overhead and scalability issues.
A common strategy is to log in the user and return back the short-lived JWT (approximately 15 minutes - as I read), together with a refresh token that the user stores in the client. The refresh token never expires, and can only be revoked. The purpose would be to avoid sending a long-lived JWT over the wire too many times, and only refresh the JWT when expired; when an attacker would get hold of the short-lived token, the attack time window is brief.
The problem is that this story seems to be full of holes when I think about it. Please help me clarify.
- A 15 minute expiration time would mean that some users might as well send a refresh token over the wire 10 times/day. That might just be as high a frequency as some user would make requests with a regular, short-lived access token. Therefore the argument of the refresh token seems questionable.
- If you question SSL, then I don't know why so many companies use basic authentication. To use JWT with refresh token, you probably should use HTTPS anyway.
- What is the benefit of JWT if you then need to store a refresh token in the session/database in order to issue a new jwt to the client. In this case, the refresh token would act as a sort of password (although I realise it's not exactly the same) that gets stored in the backend. This makes the authentication flow essentially stateful and seems to take away the benefit of using JWT altogether. Also, with a brief expiration period of 15 minutes, it means that you have a lot of overhead, needing to get a refreshed access token almost every time you check your phone if there is a 30 minutes interval. Not only is there the overhead to check the stored refresh token, additionally you need to check whether the refresh token is blacklisted, which means another performance overhead. (Edit: the last check can be removed by just removing the refresh token from the db when revoked).
- A refresh token requires multiple server roundtrips:
- 401 is returned when the access token has expired (resource server).
- A new access token needs to be requested at the auth server
- The request to the resource server needs to be re-initiated.
Can someone explain to me what I'm missing here?