I'm building a mobile app that connects to a Python Flask API and backend.

Currently, I am using JWTs for authentication. The expiration of the token is set to be 6 months in advance.

The thing that worries me is that that is a long time that the token is valid.

I've heard of people using short-lived tokens combined with a "refresh token".

I'm not sure how this works though.

So my question is:

  1. What should I do to make this more secure? Should I use refresh tokens?

  2. If refresh tokens are the best option, could someone either try to explain them to me so I have enough of an understanding to code my own implementation, or point me to some good resources where I could find such information?

1 Answer 1


Yes, 6 months is indeed a very long time because if the token gets stolen by an unauthorised third party, that party would be able to use the token for a very long time (unless detected). This is not very secure.

As you said, a slightly more secure way to do it is just as you mentioned - use refresh tokens. The way this works is that you’d have two tokens - a short-lived JWT access token and a long-lived Opaque refresh token. If the access token expires, then the refresh token can be used to get a new access token. This is more secure because even if the access token is stolen, it would expire soon. This minimizes the damage because the attacker has less time. However, what if the refresh token was stolen? In that case, unless detected, the attacker could continue to have unauthorised access to the victim’s account.

Now, how would you go about actually detecting the theft? It can be done by using what is known as ‘refreshing rotating tokens’ (see RFC 6819). However, the implementation details of that are non-trivial. If you want a quick explanation of the flow, check out my blogpost.

  • I actually read that blog post, and that's where I finally understood refresh tokens well enough to implement them.
    – Caleb H.
    Nov 14, 2019 at 13:30
  • How about storing the token into the db against the user record and return it to the user as usual. Then, prior to token expiry (maybe using setTimeout) the app will invoke the /refreshtoken endpoint that will check whether the token matches with value in the db, and if match then store a new jwt token and return it to the user. This way you always have the valid token in the app. When the user resets password then clear the token value stored against the user in the db. So the stolen token (if any) can't be used for refresh post password reset.
    – variable
    Feb 5, 2022 at 13:27
  • You can't reliably depend on the app to always be online to refresh the session right before the access token expires. You can do that as an optimisation, but not as the only means to refresh. Feb 15, 2022 at 6:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .