Reputation: 629
I am making Android app and API for it. I want to keep user logged in on the app until it logs out or reinstall the app etc. But I also want to secure API with JWT that will expire in let's say an hour.
My idea was, to keep username in the app storage after successfully logged in, and last JWT. Then when app is opened, it will communicate with API and even if the JWT is expired but 'valid' it will reissue new token. But is that secure solution? Or is there better solution for that ?
Upvotes: 3
Views: 2020
Reputation: 984
This is a classical use case of refresh tokens. The way the flow will work:
User logs in, the backend issues a short-lived (~1 hour) JWT and a long-lived refresh token and sends them to the frontend.
The frontend sends the JWT for each API call while it's still valid
In the event that the JWT has expired, the frontend should then use the refresh token to get a new JWT AND and new refresh token (rotating refresh token - see https://www.rfc-editor.org/rfc/rfc6749#section-10.4).
If the refresh token expires, then the user has to login again.
The advantage of the above method is that you can keep your APIs secure, and have the user be signed in for as long as you want.
Why do we need a refresh token (as opposed to using the invalid JWT to get a new one)?
Once a JWT expires, semantically, it should be completely useless.. if you allow it to be used to get a new JWT, then you haven't really expired it.
If an attacker gets hold of the JWT, after its expiry, then cannot continue to use it.
What if an attacker steals the refresh token?
This is where the charm of rotating refresh tokens comes into play. When you change the refresh token on each use (and revoke the older one), this allows you to 1) vastly minimise the risk from theft 2) detect that a theft has happened! And once you detect that, you can go about revoking the whole session to keep that user safe.
This and other benefits are explained in detail in this blog post
A note about the confusion of refresh tokens in other discussions
Lots of places state that you should not send the refresh token to the frontend. This is true in the case of an OAuth flow - where a third party is issuing tokens for your system's use. In this case, the "frontend" is your system (your app's frontend and backend) and the "backend" is the third party. I realise this may be a little confusing, but I am happy to chat about it here (My handle is @rp)
Final note
I would like to say that you can go ahead and implement this flow yourself (do take care of numerous race conditions and network failure issues mentioned in the above blog post), or you can check out and use our solution that does exactly (and much more) what is mentioned above in this answer.
I hope this helps!
Upvotes: 6
Reputation: 498
JWT is the only needed storage on client side. The username can be part of the claims (or payload).
Refresh tokens carry the information necessary to get a new access token. In other words, whenever an access token is required to access a specific resource, a client may use a refresh token to get a new access token issued by the authentication server. -- Sebastian Peyrott
You only need to correctly validate the token's claim and then you'll be ready to read the refresh token, the username and every other information.
Take a look at this question where they explain how to use the access token.
Upvotes: 0