I am building an application using JWT for authentication. I started doing some research and I am surprised by the lack of consensus about topics such as refresh tokens and storage for tokens.
As far as I can see JWT and OAuth are two different protocols and they follow
different specifications.
OAuth uses a refresh token in order to get a new access token but in order to do so, there are 4 entities involved in the process, The User (The Front-end), The Resource Server (Facebook, Google, etc), The Client Server (e.g PHP Web Application) and the Authorisation Server.
In that case, it makes sense to have a refresh token because in order to refresh the token, it is required a client id and a client secret (issued by the Resource/Auth Server) which is known only by the Client Server and not by the User (User front end Side). So the refresh token would be useless for an attacker who stole the refresh token.
But my question is, for an application which is not authenticated against a third party Resource Server such as Google, Facebook and so on, Is it really useful to have a refresh token, why don’t make the JWT token last as long as a refresh token.
On the other hand, I could see that when a refresh token is used along with a JWT token as This Article states, the refresh tokens are usually subject to strict storage requirements to ensure they are not leaked. However, I could not find What/Where and How I can store this token on the User side in order to meet those strick storage requirements.
Can someone please enlighten me about all of this? Thanks.
Note: I want to highlight that my web app is NOT using third party application to authenticate (Facebook, Google etc), it is Single Page App in the front-end side and in the server side a single API which issue a JWT token. My questions are focused on this kind of architecture
2
Answers
JWT tokens should have a limited lifetime to limit their usefulness in case they’re stolen. Refresh tokens are used to get new access tokens without involving the user and should only be used from a confidential client.
I describe the OAuth2 flows and use of refresh tokens in more detail in this answer.
In short, you are right, if you store the refresh and access tokens the same way, and your app itself is the identity provider, it doesn’t make much sense to use a refresh token – it can be stolen the same way as the actual access token.
However, consider two things.
One, the access token is sent with every request. If you look at recent (and older) https vulnerabilities, it may be possible sometimes for an external attacker to extract bits of the https stream (under certain circumstances, depending on the specific vulnerability). This is usually not straightforward, and probably not possible on every request. If you have a short lived access token and a longer lived refresh token that is rarely used, even if the access token is compromised through such an ssl/tls attack, the refresh token might not be. This is a very slight benefit, but still.
Also, you can potentially store the refresh token differently. One of the main risks to these tokens is XSS. If you implement your identity provider in a way that it issues refresh tokens in httpOnly cookies, then the refresh token cannot be accessed by Javascript, so XSS cannot be used to read it. You can still store the access token in a Javascript object or localStorage or whatever, and if it’s compromised, it is at least short lived. This is good, because XSS usually requires user interaction, so if it worked once, because for example the user clicked a link or visited a particular page, it is not guaranteed that he will do it again, so reading the next access token may be difficult for an attacker. Again, it’s not a huge benefit, but it is an advantage.