Refresh Token implementation in Reactjs
Tags: webdev, javascript, react, tutorial
Published: 2023-01-09 07:58:10

In this tutorial, you will learn how to use refresh tokens to maintain access to a user's resources in your React application. Refresh tokens allow the application to obtain a new access token without requiring the user to re-authenticate, making it a useful tool for long-lived or background applications. Follow along as we walk through the process of implementing refresh token functionality in React.

 **You** can check my previous post about [Refresh Token implementation in nodejs](https://dev.to/chafroudtarek/refresh-token-implementation-in-nodejs-with-typescript-33ed)

👋 You can also check my weekly posts in [Linkedin](https://www.linkedin.com/feed/update/urn:li:activity:7013052112884396032/)


**Requirements**

- Basic knowledge of reactjs.
- Basic Knowledge of axios.


To get started, create a new file in your React app which you can name "axios.js" and place in a "helpers" folder, or anywhere else in your app as desired. This file will be used to set up and customize your application's HTTP requests with the axios library, and it will include all the logic for your refresh token implementation. It's a simple process, so let's get started!

start with :

```
const customFetch = axios.create({
  baseURL: "http://localhost:3000/api/",
  headers: {
    "Content-type": "application/json",
  },
  withCredentials: true,
});

```
This code creates a custom instance of the axios library with a specific configuration.

- The **baseURL** field sets the base URL for all API endpoints that this instance will be used to call.In this case, it is set to
"http://localhost:3000/api/".
- The **headers** object defines the default headers that will be sent with every request made using this instance.
- the **withCredentials** a boolean value that indicates whether or not to send the "Cookie" header with requests. When set to true, the "Cookie" header will be sent with every request.

You can use this custom instance of axios to make HTTP requests in the same way as the default axios object. The main advantage of using this custom instance is that it includes the default configuration specified in this code, so you don't have to include these options in every request.


▪️ To clarify, this interceptor can also be added for the purpose of retrieving the accessToken from local storage and including it in the Authorization header of the requests. 

```
customFetch.interceptors.request.use(
  async (config) => {
    const token = getTokenFromLocalStorage();
    if (token) {
      config.headers["Authorization"] = ` bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
```

Now we will focus on the crucial part of this blog: the code below is responsible for refreshing the access token by sending a request to the server with the refresh token and receiving a new access token in the response.

```
const refreshToken = async () => {
  try {
    const resp = await customFetch.get("auth/refresh");
    console.log("refresh token", resp.data);
    return resp.data;
  } catch (e) {
    console.log("Error",e);   
  }
};

```
This is a function that sends a GET request to the "auth/refresh" endpoint using the customFetch instance of axios. If the request is successful, the function logs the response data to the console and returns it. If the request fails, the function logs the error to the console

▪️ The important interceptor for today is the code below:

```
customFetch.interceptors.response.use(
  (response) => {
    return response;
  },
  async function (error) {
    const originalRequest = error.config;
    if (error.response.status === 403 && !originalRequest._retry) {
      originalRequest._retry = true;

      const resp = await refreshToken();

      const access_token = resp.response.accessToken;

      addTokenToLocalStorage(access_token);
      customFetch.defaults.headers.common[
        "Authorization"
      ] = `Bearer ${access_token}`;
      return customFetch(originalRequest);
    }
    return Promise.reject(error);
  }
);
```

The interceptor function takes two arguments: a response object containing the response data, and an error object in case of a rejected response. The function returns the response object or a rejected Promise with the error object.

The interceptor first checks if the response has a status of 403 (Forbidden) and if the _retry property of the original request is not set. If both conditions are met, it sets the _retry property to true and calls the refreshToken function to attempt to refresh the access token. If the refresh is successful, the new access token is added to local storage and the Authorization header of the customFetch instance is updated with the new token. The original request is then retried with the updated customFetch instance. If the refresh is not successful or if the original response did not have a status of 403, the interceptor returns a rejected Promise with the error object.

This interceptor will be called for every response received by the customFetch instance of axios, and will attempt to refresh the access token and retry the request if the access token has expired and the server returns a 403 status code.

**In conclusion:** In this tutorial, we learned how to use refresh tokens to maintain access to a user's resources in a React application. We set up a custom instance of the axios library with a specific configuration, including an interceptor to add an Authorization header with a bearer token to every request. We also implemented another interceptor to handle expired access tokens by attempting to refresh the token and retrying the original request. With these techniques, we can keep our application authenticated and maintain access to the user's resources without requiring the user to continually provide their login credentials.