All about JWT (part-1 basics)

Javed Akhtar
11 min readFeb 18, 2023

--

All about JWT (part-1 basics)

Understanding JWT basics part-1

Have you

- ever logged in or sign in on any web platform?
- ever used/created any api which requires authentication/authorization?

If yes, then you may have used JWT as a front-end or back-end engineer 💻.

Hey! Geeks welcome to my third article on this platform.
Let me tell you how I got introduced by JWT for the first time in my carrier. I got to know about JWT when I was trying to solve a problem in which users of a web app used to get logged out frequently with error page. After debugging I found that it was due to JWT token getting expired and not getting refreshed and i.e. because api call was getting failed with invalid token and that was not handled in front-end react application 🤔.

Initially it was so confusing😕, I was not even aware of JWT and how to implement it (I was doing internship in Bengaluru). I solved that problem but it took me a lot of time as beginner😞. So, I decided that one day I will implement it from scratch and will share this topic the way I wanted to understand it. So, here it is, we are going to understand and implement JWT in three parts 😄🎉.

Youtube Video Link: All-About-JWT (all 3-parts of this article explained)

So, bring your snacks with you, enjoy 😄 while learning 🧑‍🎓.

Remember: You give space to creativity when you take break and see how beautiful is the surrounding

Table of contents

  1. What is JWT(JSON Web Token)?
  2. How JWT is used for authentication/authorization?
  3. Why JWT?
  4. How to secure JWT?
  5. How we are going to implement it using REACT and NODE?
  6. Front-end implementation plan
  7. Back-end implementation plan
  8. Important Links
  9. Final Thoughts

What is JWT(JSON Web Token)?

JWT is a token which is used to verify the owner of a json data.
It is a string which is base64url-encoded(not encrypted) divided in three subsections separated with dot. Lets try to understand it by an example:

Below is an example of how a JWT looks like (Check it is divided in 3 sections, I have marked first and last part of it as bold for better visibility):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIwLCJuYW1lIjoidGVzOCIsInVzZXJfbmFtZSI6InRlc3Q4IiwidXNlcl90eXBlIjoidXNlciIsImF2YXRhciI6InZpb2xldCIsImlhdCI6MTY3MzI4MzU0OSwiZXhwIjoxNjczMjgzNjA5fQ.PKkGZvyjjTeYqKZrH6tvSF7AJX3tyvPtLLTRJdYREZE

Lets try to understand each of these 3 subsections:

  1. Header section(eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9) :
    When you decode this base64url encoded string (click me to decode), you will get {“alg”:”HS256",”typ”:”JWT”}. It contains information about the token itself and this information is used for generating third part of the token which is signature.
  2. Payload section (eyJpZCI6MTIwLCJuYW1lIjoidGVzOCIsInVzZXJfbmFtZSI6InRlc3Q4IiwidXNlcl90eXBlIjoidXNlciIsImF2YXRhciI6InZpb2xldCIsImlhdCI6MTY3MzI4MzU0OSwiZXhwIjoxNjczMjgzNjA5fQ) :
    When you decode this base64url encoded string, you will get
{"id":120,"name":"tes8","user_name":"test8","user_type":"user","avatar":"violet","iat":1673283549,"exp":1673283609}

This part is the payload of JWT which stores information about the token and any other entity in JSON format. Usually, a JWT used for authentication and to store some crucial information about the user, such as the user ID and user role. Lets understand above decoded info:

iat: Stores the time(in numericDate) the token was issued at.
exp: Provides an expiration time(in numericDate) to the token.
rest all are self explanatory payload which can be used as needed.

3. Signature section (PKkGZvyjjTeYqKZrH6tvSF7AJX3tyvPtLLTRJdYREZE) :
When you decode this base64url encoded string, you will get:
<f7koH^%},%
It is a Message Authentication Code(signature) that is used to verify the token was not modified or generated by an outsider except the authorized application servers.

This signature is generated by signing the combination of JWT header section and payload section using an encryption algorithm(mentioned in header section) and a secret stored in the server. Only someone who has the token’s header and payload and the server secret can generate the signature accepted by the server. So, it is important to use a strong secret to encrypt tokens and securely store it in the server.

How JWT is used for authentication/authorization?

Lets try to go through them in points for better understanding:

  • When a user sends a login request to server, server will validate the user with credential matching with DB. This is when you login to any app using username and password.
  • Now, the server will take the username and password and will verify it using database(DB). Once the user is verified successfully, server will generate a JWT token based on parameters provided such as payload, secret key from DB and signing algorithm. This token will be sent to client in response to the login request authenticated successfully.
  • Whenever a client wants to use service of the server(say any api), the client will send the JWT token instead of credential(username/password). This saves DB operation headache and creates smooth process 🔥.
  • Once a request comes to server with a token, the server takes the header and payload which is part of the token(explained in start of this article) and generates a test signature with the secret key. This test signature and the signature present in the token from client is matched by the server, if match found then user is authenticated and client will receive 200 response ✅. If the signature does not match then it means the token is either compromised or expired and 401 error ❌ will be reported to the client.

Why JWT?

  • HTTP protocol is stateless, that means a new request won’t know anything about the previous one. So, how to maintain session 👉
  • Server Side Sessions was a solution to the statelessness of HTTP, but these, in the long run, were a threat to our scaling abilities. This because if you replicate your server on multiple instances, it will be difficult to understand which session is active on which instance. We can use session id in DB but not efficient solution.
  • 🔥 JWT is self-contained, that means it contains every information needed to allow or deny any given requests to an API. No need server side session anymore.🔥
  • JWT is stateless by design, so we don’t have to fight with the stateless design of HTTP 🔥.

Note: JWT is encoded, not encrypted have it in mind. So, do not store sensitive information in JWT payload 📝.

How to secure JWT?

  1. If the secret key 🔑(used to generate JWT) gets compromised, it is a big threat, JWT system will fail. So, keep it in secure place and maybe keep changing ✅ . You can keep separate key for each user but again you will have to maintain it somewhere in DB for mapping and hence not recommended ❌ as JWT will be different with same key for each user each time.
  2. If the Token(access token) gets stolen then also it is a problem because it works as similar as credential. So, to solve this we need to use JWT token expire feature. While generating the token, server can set expiry time to the token. So, if the token received is expired, then the token is invalid even if all is okay in the token.
  3. However, this action does not eliminate the threat of stolen tokens, just reduces the chances of it leading to a serious attack. So, new token needs to be generated and can be done only when user will send a login request with credential. But we can not expire token very quickly as because the user will get frustrated 😤 to keep login again and again to create a new token.

So, here comes a concept known as refresh token 🔥. A refresh token is also a JWT token with a longer expiration time. It is used to issue a new JWT token (AKA access token) every time the old access token expires. Access token is a JWT token but with a shorter expiration time.
Note: When refresh token gets expired, user/customer should be logged out from the system and redirected to login page to login with credential📝.

How we are going to implement it using REACT and NODE?

Lets first summarize what we have understood so far. The access token is the token that is sent back and forth between the client and the server and has a short expiration time. However, when the access token expires within a short time, instead of asking the user to log in again, the server uses the refresh token to generate a new access token. Since refresh token has a long expiration time and it is not being passed to the client-side in any case, we should store them in a backend database or store them in browser cookie with httponly secure samesite and maxAge etc attributes and hence make sure the cookie can only be accessible by server.

If an attacker somehow gets access to a refresh token, it’s a serious security threat to the system and the owner of the refresh token given their long expiration time. So, refresh tokens must be stored under maximum security measures just like the secret key of JWT.

So, lets discuss a design/plan which we are going to implement in 2nd-part and 3rd-part of this article using Node in back-end and REACT in front-end.

This plan will include how a near to prod authentication system can be implemented. I have used the word “near to prod” because there are lot of extra and best practices can be used upon the plan which may be necessary or may not be in some cases. You may find such more things missing which you should implement in your prod server. My focus is mainly on authentication system with some (not all) best practices in front-end and back-end. I hope you understand that🤞.

Front-end implementation plan

Front-end will raise a request to server with payload as username and password. If the credentials are not valid, front-end will receive 401 error which we will use to show message to user indicating “invalid user”.
If the user is verified, front-end will receive 200 response with both Access and Refresh token. The access token will be received in payload of the response(we will store it in localstorage) and the refresh token will be received as cookie which can only be accessible by server for security reasons.

  1. The next time any secured api we will request to server, we will send the access token with the request in header so that the request will be authenticated by server and this is how we don’t need to send user password to authenticate but it’s temporary credential AKA Access Token. We will intercept the request using axios to achieve this.
  2. After sometime, the Access token will be expired and will throw 401 error. We will catch this error response in the axios interceptor and will hit refresh token endpoint /rtoken to the server with option withCredentials set to true. This will make sure that the request at endpoint /rtoken will include the cookie having refresh token (do you remember, we have stored this refresh token in cookie when the user was logged in successfully?). Here following two things may happen :
  • When refresh token is valid: Server will send a new access token. We will store it in localstorage. After this we can reload the page so that next all requests will be raised with new access token.
  • When refresh token is expired: Server will throw error, we will catch that error and logout the user and redirect to login page so that user can login using username and password.

Back-end implementation plan

In back-end (hackers backend 🤓) we will create following endpoints to understand JWT:

  • hackers/register : using which we will register new users and save password by hashing it using bcrypt library.
  • hackers/login : using which we will validate already registered user and respond with refresh and access token
  • hackers/rtoken : using which we can refresh access token with the help of a valid refresh token.
  • hackers/top : A secured api to fetch all hackers details. Since this end point is secured, consumer of this api needs to be authenticated using JWT. So, this is the example api where will use JWT for authentication.

Lets understand above endpoints in detail now 👉:

  • 👉A user of the hackers web app will first register to the website and hence hackers/register endpoint will be called. In this endpoint logic, we will do some basic checking of the data sent to register and then we will store that information in DB (hashed password will be stored for security reasons). If the registration data failed in basic validation or user is already registered then we will respond 409 error ❌. If the data is valid then we will store the info in DB and respond with 200 with message “user registered successfully” ✅.
  • 👉After registration, user will login hence hackers/login endpoint will be called. In this endpoint we will validate the user and if not valid respond with 401 ❌. If user is valid then we will get user details and use that as payload in generating access token and refresh token (using the npm package jsonwebtoke). Here refresh token will be generated using user data, refresh-secret-key, and expiry time.
    Similarly access token will be generated but with “access-secret-key” and not with “refresh-secret-key” and the expiry time will be less compared to “refresh token expiry time” because we don’t want user to logout very frequently as it will be bad customer experience.
    We will return two response in this case. First we will respond cookie(with expiry time) with refresh token which will be stored in browser and will not be accessible to front-end code. And second we will respond 200 with access token ✅.
  • 👉Whenever Access-Token will get expired, front-end will raise refresh request and hence hackers/rtoken endpoint will be called. In this endpoint we will first check if refresh token is sent in cookie or not. If refresh token found then we will check if refresh token is expired or not. If expired then throw 401❌. If refresh token is valid then simply generate a new access token for the user and respond with it✅.
  • 👉To show all hackers list in a page, front-end app will raise a request to the hackers/top back-end endpoint. Before accessing this endpoint, a middleware will be used which will authenticate the request. The middleware will verify the token and if validated, then it will pas the control to the endpoint logic which will respond 200 with all hackers in payload ✅.
    And if not validated then the middleware will simply respond with error 401 ❌ with custom error name so that front-end can use it.

That’s it, we are done with our plan. Too much theory, lets jump to code now ✍️.

Image explaining working of JWT with access and refresh token using 3 endpoints.

Important Links

Article explained on YouTube with code

Final Thoughts:

  • I hope this article helped you to understand JWT concept and encouraging you to implement it by yourself.
  • I would love to hear your feedback on this article, you can encourage me by clapping👏 and share feedback by commenting what you liked 👍 and what you didn’t 🥲. Please let me know by commenting 💬 if I have explained something which needs to be corrected because at the end, this is how we improve information on internet.
  • It’s 💯 OK if you don’t want to share this article to anyone, but please share your learning to people/developers/juniors/seniors who don’t know yet about JWT implementation, this will serve the sole purpose of this article. Thanks a lot for spending time in reading this article specially in this era of short videos where we get bored so easily.

This is Javedinfinite signing off 🫡

--

--

Javed Akhtar

I am a software engineer. I love javascript and it's library(React). I am also a writer, cook, singer, youtuber. website: https://javedinfinite.com