DEV Community

Cover image for Authentication with JWT Tokens in React and Express.js
DEVLOKER
DEVLOKER

Posted on

Authentication with JWT Tokens in React and Express.js

Hello developers!

Authentication is a crucial aspect of modern web development, ensuring that users can securely access resources and data. One popular method for implementing authentication is through the use of JSON Web Tokens (JWT). In this post, we'll delve into the concept of JWT tokens (accessToken & refreshToken), how they work, and then explore a practical implementation using React for the client-side and Express.js for the server-side.

Understanding JWT Tokens

JSON Web Tokens (JWT) are an open, industry standard RFC 7519 method for representing claims securely between two parties. They provide a compact and self-contained way to transmit information between parties as a JSON object. JWT tokens consist of three parts: a header, a payload, and a signature.

1. Header

The header typically consists of two parts: the type (typ) of token which is "JWT", and the signing algorithm (alg) being used, such as HMAC SHA256 or RSA.

{
  "typ": "JWT",
  "alg": "HS256"
}
Enter fullscreen mode Exit fullscreen mode

2. Payload

The payload contains the claims such as the expiration-time (exp) and Issued-at (iat), which are statements about the user and additional data. Custom claims are usually also included, depending on the purpose of the token.

{
  "iat": 1713636257, // Issued-at
  "exp": 1713636557, // expiration-time
  "id": "ab86a1e1ef70dff97959067b723c5c24" // custom claim userId
}
Enter fullscreen mode Exit fullscreen mode

3. Signature

The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn't changed along the way. The signature is created by combining the encoded header, the encoded payload, a secret key, and the specified algorithm.

The three parts (header, a payload, and a signature) are encoded separately using Base64url Encoding RFC 4648, and concatenated using periods to produce the JWT, something like this jwt.io:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFiODZhMWUxZWY3MGRmZjk3OTU5MDY3YjcyM2M1YzI0IiwiaWF0IjoxNzEzNjQyMDUxLCJleHAiOjE3MTM2NDIzNTF9.hfRGkwX3ASdMm-tzR5NA_vy6DrTL7i6Doxt1U99LGUE

Authentication with JWT Tokens

Access Token

In the context of authentication, the access token is a JWT token that represents the authorization granted to the user. It typically contains information such as the user's ID and any relevant permissions. Access tokens have a short lifespan to minimize the risk if they are intercepted. They are used to access protected resources on the server.

Refresh Token

Alongside the access token, a refresh token is often issued to the client during authentication. The refresh token is also a JWT token but with a longer lifespan. Its purpose is to obtain a new access token once the current one expires. Refresh tokens are securely stored on the client-side and are only sent to the server when requesting a new access token.

How they work!

  • When a user logs in, the server generates a JWT token and sends it back to the client. This token is then included in subsequent requests to authenticate the user. The server can verify the token's authenticity and extract the necessary information from the payload to grant access to protected resources.
  • When the access token expires, the client can use the refresh token to obtain a new access token without requiring the user to log in again. The server receives the refresh token, verifies its authenticity, and issues a new access token if the refresh token is valid. This process helps maintain a seamless user experience while ensuring security by regularly rotating access tokens.

So, both JWT tokens (access tokens & refresh tokens) can implement robust authentication mechanisms that protect user data while providing a seamless user experience.

JWT Authentication concept

Implementation with React and Express.js

In our implementation, we'll use React with Redux Toolkit on the client-side and Express.js on the server-side. Our server will consist of two parts: an authentication server and a resource server.

  • The authentication server: running on port 8800, will handle login, logout, and refreshing access tokens. We'll secure the login and refresh routes using express-rate-limit to prevent brute force attacks and limit the number of requests.
  • The resource server: running on port 8080, will expose a protected resource accessible only to authenticated users.

Code Walkthrough

Let's dive into the code to see how it all comes together. We'll start with the client-side implementation in React, where we'll manage authentication state using Redux Toolkit. Then, we'll explore the server-side implementation in Express.js, where we'll define routes for login, logout, and refresh-access-token.
You can find the complete code repository JWT-Practice, which includes detailed comments to guide you through each step.

Happy coding! 🚀

Feel free to adjust the content as needed to fit your style and the specific details of your implementation!

Future Perspectives

As we wrap up, it's essential to consider future perspectives for our authentication system. One such perspective is enabling users to logging in from different devices securely. This can be achieved by associating each JWT token with a unique device identifier and implementing session management to revoke tokens when necessary.

In conclusion, JWT tokens provide a robust and scalable solution for authentication in modern web applications. By understanding their inner workings and implementing them in our projects, we can ensure secure access to resources while providing a seamless user experience.

I hope this post provides valuable insights into authentication using JWT tokens with React and Express.js. Feel free to leave any questions or feedback in the comments below!

Top comments (0)