0

I'm programming a mobile app which makes use of REST services.

Some of the services are for logged users, so I have a login endpoint which lets me enter my credentials and get a JWT token for accessing protected APIs.

I want to be able to login one time and have the app remember me without asking me to login again each time I close and reopen it.

I came up with two choices so far:

  • Make a long lasting JWT, which doesn't expire. That way, I can just save it and use it each time I'll need to access protected APIs. This can be unsafe because if the token goes in wrong hands, the "hacker" would have an access key that never expires. That potentially is a permanent access to the application.
  • Save username and password in the app's local storage. That way I can have expiring JWTs that can be refreshed, and if the last token expired I can call the login API again with the same username and password to obtain a new token. This can be unsafe because I'd be saving the user credentials on the phone, it seems risky to me.

So what is the common approach to this issue?

1
  • What threats do you need to protect against? Hackers sniffing an access token and impersonating a user with it? Hackers getting physical access to the phone and abusing the user's account? Something else? Commented Oct 3, 2018 at 14:29

2 Answers 2

2

Long lasting tokens are usually not a problem. If an attacker compromises the user's device to the point where they could exfiltrate the token then they could possibly also capture passwords anyway. If the user willingly extracts the token to use it externally, then no harm done: the token should identify the user, not your app.

But the problem with long-lasting JWT tokens is that they cannot be revoked without storing centralized state. One possible solution: do not use JWT. Instead of giving the user a JWT token with signed claims, a long-lived but revocable session identifier may be preferable. Of course, that requires that you store all active sessions in your backend. But this makes use cases like “sign out all active sessions” possible, in case the user's devices or their tokens are compromised (possibly also due to a problem on your part).

There are in-between solutions you can try, but my guess is they would be more complex. For example, you could expire the JWTs after a few days, but automatically issue new tokens regularly. This way, a user would not have to sign in if your app is able to run regularly (you could schedule a background task to refresh the token). But the token provider can refuse to refresh a token if the app-provided still-valid token is marked as revoked. E.g. you could reject all tokens that were issued before some point in time, or reject tokens with a specific ID. Other services that use this token only have to check the signature, not the revocation status. This limits the window of opportunity for misusing stolen tokens, but doesn't really prevent anything.

In the end, the correct choice depends entirely on your security model. What threats are you defending against? What is the risk and impact of this threat? There is no perfect security, so which threats are important? E.g. the typical banking app would come to very different conclusions than the typical microblogging app.

2
  • isnt the refresh token usualy revokable and the long lived one?
    – Ewan
    Commented Oct 3, 2018 at 18:00
  • @Ewan sure, that also works. The key point is that the main tokens are reasonably short lived, and that main token validation does not have to consider refresh token revocation. My answer describes a variant in which the main token is identical with the refresh token.
    – amon
    Commented Oct 3, 2018 at 18:43
0

So the most common approach I have seen is to use oauth2 with a short (5min) expirey access token and a long (1 month) expirey refresh token.

This means that once the user logs in, they can abstain from using the app for up to a month before they will be asked to re login.

The access token is sent with every request to resourse servers and the refresh token is used every 5min to get a new access token and refresh token from the auth server.

If the user wishes to 'log out' they can ask the auth to revoke their refresh token. After that, their access token is only good for 5min and they will need to log in with their user/pass again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.