Recently I could not get any idea, what to write a post about. Simultaneously I was working on how to do JWT authentication. It took a lot of time for me to figure out how to do JWT authentication properly. So, in this series of posts, I'm going to talk about how to do JWT authentication in a proper way.
Did you know? JWT stands for JSON Web Token
There are two kinds of token - Access Token and Refresh Token. Access Token is the main JWT token. It is used to authenticate the user and give the user access to protected routes.
As you can tell, Access Token is pretty powerful. So, keeping it permanently active is not a good idea. Hackers can use that access token and do malicious requests to our server. Generally, we add expiry to our access tokens so that, the tokens are invalid after some time.
But this causes a new problem. Whenever the access token expires our authenticated user will no longer be authenticated. This causes a new problem. Every time, the access token expires the user needs to be unauthenticated. While this might be good for some specific scenarios, but most of the time you want your user experience to be seamless once they have logged in.
In such a condition, refresh token comes in. It will automatically refresh the access token, without the user even knowing that their token has expired. Refresh tokens generally have a longer lifespan than access token. However, they are not as powerful as an access token as they can only be used to generate a new access token.
So, let's talk about the basic workflow of JWT Authentication. The frontend makes a request with the username and password. Then that username and password are checked against the database. If the username and password match a user then an access token and a refresh token are generated with any unique information from the user(which can later be used to identify the unique user).
Now, the tokens are sent to the frontend and stored for future use. This access token will be sent with every request to obtain sensitive data from the backend. The tokens need to be stored properly so that they are not lost after a page reload. The main question now arises how to store these tokens. There are three options for storage -
Localstorage: The first option to store tokens will be to use localstorage of the browser. However, these tokens are not secure enough and vulnerable to XSS attacks.
Cookie: HTTP only Cookie is a good option to avoid XSS attack. But in that case, the tokens are vulnerable to CSRF attacks.
A mix of Cookie and runtime variable: According to me this is by far the best method to store the tokens. In this method, you store the access token inside a JS variable in the frontend while you store the refresh token in HTTP Only Cookie. In that way, your cookie if compromised will leak only the refresh token which alone can not do any damage to the system. Every time your page refreshes you have the refresh token to generate a new access token.
That will be it for this post. In the next post, I will discuss how I implemented this concept with express and vue.js.