DEV Community

Kartik Sharma
Kartik Sharma

Posted on

4 1

Automate Refresh Tokens with Axios Intercepters!

The Problem

A while back, I was working on a small project that interacted with the Salesforce API and performed CRUD operations on my objects. I was using React.js (with no backend setup, just a static frontend). However, I encountered a problem while working with the API. The access token I generate using the OAuth method is valid for only 24 hours! This means I have to manually generate a new token by making an OAuth API call every time I refresh the application.

I don’t like how my application is making unnecessary API calls to Salesforce OAuth to refresh the token, even when it hasn’t expired. To overcome this, I want to implement the following logic in my code:

axios.get('https://www.someapi.com/fetch-data').then((data)=> {
// doing something with the Data
},{}).catch((error)=> {
    if(error.response.statusCode === 401){
        // If Token Expired
        RefreshToken()
        window.alert("Session Expired Please Reload the Window!")
    }
})
Enter fullscreen mode Exit fullscreen mode

My logic is essentially this: if there’s a 401 response from the API endpoint, I make a refresh token API call, store the new token in local storage, and then prompt the user to reload the page to use the newly generated token for subsequent API calls. However, this approach relies on the user to perform an additional action, which could be automated to improve the user experience and avoid unnecessary interruptions.

Using Axios Intercepters

Let’s see it in action

axios.interceptors.response.use(
  (response) => response,
  async function (error) {
    const originalRequest = error.config;
    if (error.response.status === 401 && !originalRequest._retry) {
      if (isRefreshing) {
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject });
        })
          .then((token) => {
            originalRequest.headers["Authorization"] = "Bearer " + token;
            return axios(originalRequest);
          })
          .catch((err) => {
            return Promise.reject(err);
          });
      }

      originalRequest._retry = true;
      isRefreshing = true;

      return new Promise((resolve, reject) => {
        initiateNewAccessTokenApi()
          .then((token) => {
            axios.defaults.headers.common["Authorization"] = "Bearer " + token;
            originalRequest.headers["Authorization"] = "Bearer " + token;
            processQueue(null, token);
            resolve(axios(originalRequest));
          })
          .catch((err) => {
            processQueue(err, null);
            reject(err);
          })
          .finally(() => {
            isRefreshing = false;
          });
      });
    }

    return Promise.reject(error);
  }
);

Enter fullscreen mode Exit fullscreen mode

Code Explanation

What I did was attach a middleware to every request that Axios makes, checking if any response comes back with a 401 HTTP status code. If it does, I re-initiate the access token by calling the refresh token API, store the new token in local storage, and automatically re-trigger all the previous API calls that were denied. That’s it! No more asking the user to ‘reload the window!’ 😸

I hope this helps and integrates well with your work!

Tiugo image

Fast, Lean, and Fully Extensible

CKEditor 5 is built for developers who value flexibility and speed. Pick the features that matter, drop the ones that don’t and enjoy a high-performance WYSIWYG that fits into your workflow

Start now

Top comments (1)

Collapse
 
arun05hp profile image
Arun Kumar

Great article 👍

Neon image

Next.js applications: Set up a Neon project in seconds

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay