• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

The Programming Expert

Solving All of Your Programming Headaches

  • HTML
  • JavaScript
  • jQuery
  • PHP
  • Python
  • SAS
  • Ruby
  • About
You are here: Home / React / React Axios Interceptor to Prevent Infinite Loops in JWT Authentication

React Axios Interceptor to Prevent Infinite Loops in JWT Authentication

November 24, 2021 Leave a Comment

Dynamic web applications are very popular these days, and many web applications need to have some sort of user management to be able to best serve the app users.

One popular frontend and backend combination is using React (Javascript) on the frontend and Django (Python) on the backend.

There are many different ways to do user authentication in web applications, but I’d like to focus in this article on JWT Authentication.

JWT Authentication with Django is relatively easy with a handful of packages already out there.

The non-obvious piece comes with how do the browser and server interact to make sure that everything functions between Django and React.

One problem that sometimes will happen with various authentication packages is that an infinite loop will occur and a refresh token needs to be provided to the server for authentication.

Infinite loops are never good for an application, and in this post, I’m going to share with you how you can implement an interceptor using Axios in React to prevent infinite loops.

React Axios Interceptor to Prevent Infinite Loops in JWT Authentication

The following code is how you can prevent infinite loops in React using Axios.

On the backend, I’m utilizing rest_framework_simplejwt which provides us an access token (access_token) and refresh token (refresh_token).

When a user logs in, we receive an access token and refresh token from the server. Then, if the user goes to access some protected content, the server needs the access token to serve the requested data.

Sometimes the server throws a 401 unauthorized error when we are authorized to access that information – in this case, we need to include some extra code to ensure that we get the information. After receiving this 401 error, we then should check the refresh token and receive a new access token.

The problem comes in when the server continually keeps throwing 401 errors even after receiving new access tokens.

The key is to create a second axios instance which will handle the refresh request.

The code below should handle both of these problems, both the 401 unauthorized errors and the infinite loops.

If at the end, the user is unauthorized, this sends the user to ‘/’.

import axios from 'axios';

const baseURL =  "http://localhost:8000/api";

const AuthService = axios.create({
    baseURL: baseURL,
    timeout: 60000,
    headers: {
        'Authorization': localStorage.getItem('access_token') ? "JWT " + localStorage.getItem('access_token') : null,
    }
});

const RefreshService = axios.create({
    baseURL: baseURL,
    timeout: 10000
});

AuthService.interceptors.response.use(
    response => response,
    error => {
        const originalRequest = error.config;

        // Prevent infinite loops
        if (error.response.status === 401 && originalRequest.url === baseURL + '/token/refresh/') {
            window.location.href = '/';
            return Promise.reject(error);
        }

        if (error.response.data.code === "token_not_valid" &&
            error.response.status === 401 && 
            error.response.statusText === "Unauthorized") 
            {
                const refreshToken = localStorage.getItem('refresh_token');

                if (refreshToken){
                    const tokenParts = JSON.parse(atob(refreshToken.split('.')[1]));

                    // exp date in token is expressed in seconds, while now() returns milliseconds:
                    const now = Math.ceil(Date.now() / 1000);
                    console.log(tokenParts.exp);

                    if (tokenParts.exp > now) {
                        return AuthService.post('/token/refresh/', {refresh: refreshToken})
                        .then((response) => {
            
                            localStorage.setItem('access_token', response.data.access);
                            localStorage.setItem('refresh_token', response.data.refresh);
            
                            AuthService.defaults.headers['Authorization'] = "JWT " + response.data.access;
                            originalRequest.headers['Authorization'] = "JWT " + response.data.access;
            
                            return AuthService(originalRequest);
                        })
                        .catch(err => {
                            console.log(err)
                        });
                    } else {
                        console.log("Refresh token is expired", tokenParts.exp, now);
                        localStorage.removeItem('access_token');
                        localStorage.removeItem('refresh_token');
                        AuthService.defaults.headers['Authorization'] = null;
                        window.location.href = '/';
                    }
                } else{
                    console.log("Refresh token not available.")
                    window.location.href = '/';
                }
        }
      
      // specific error handling done elsewhere
      return Promise.reject(error);
  }
);

export default AuthService

I hope that this code snippet is helpful for you and helps you solve your infinite loop problems with JWT Authentication in your web app.

Other Articles You'll Also Like:

  • 1.  JavaScript onfocus – Changing Form Styles with the onfocus Event
  • 2.  Remove the Last Element From Array in JavaScript
  • 3.  How to Use JavaScript to Round Up Numbers
  • 4.  Using JavaScript to Convert String to Integer
  • 5.  Using JavaScript to Get Today’s Date
  • 6.  Remove the First and Last Character From a String in JavaScript
  • 7.  Using JavaScript to Remove Duplicates From Array
  • 8.  JavaScript join – Create String from Elements in an Array
  • 9.  Add Days to a Date Using JavaScript
  • 10.  Using JavaScript to Get Substring Between Two Characters

About The Programming Expert

The Programming Expert is a compilation of a programmer’s findings in the world of software development, website creation, and automation of processes.

Programming allows us to create amazing applications which make our work more efficient, repeatable and accurate.

At the end of the day, we want to be able to just push a button and let the code do it’s magic.

You can read more about us on our about page.

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

About The Programming Expert

the programming expert main image

Welcome to The Programming Expert. We are a group of US-based programming professionals who have helped companies build, maintain, and improve everything from simple websites to large-scale projects.

We built The Programming Expert to help you solve your programming problems with useful coding methods and functions in various programming languages.

Search

Learn Coding from Experts on Udemy

Looking to boost your skills and learn how to become a programming expert?

Check out the links below to view Udemy courses for learning to program in the following languages:

Copyright © 2023 · The Programming Expert · About · Privacy Policy