Problem with Axios interceptor in live environment

When developing an application and trying to use a refresh token, I am encountering an issue. Authentication is done using ADFS which provides an id_token that expires hourly and a refresh token that lasts 8 hours.

The script below works flawlessly in development mode for refreshing the tokens.

However, in production, while new tokens are obtained, the original request is never retried. The difference in behavior between webpack-dev-server and production is what I am trying to figure out.

Any assistance on this matter would be greatly appreciated!

P.S. Babel Presets Being Used: babel-preset-env and babel-preset-stage-2

axios.js

import axios from 'axios'

// Set baseURL based on environment
const baseURL = process.env.NODE_ENV === 'development' ? '//localhost:3001/api' : '/api'

// Create axios instance with correct baseURL
const instance = axios.create({
  baseURL
})

// Intercept responses
instance.interceptors.response.use((response) => {
  return response
}, async (error) => {

  // Extract config, status and data from the error
  const { config, response: { status, data } } = error

  // Retrieve tokens from local storage
  let currentTokens = JSON.parse(localStorage.getItem('tokens')) || null

  // Check if response errors at 401, token is valid and we have tokens in localStorage
  if(status === 401 && data.token_invalid === undefined && currentTokens && !config._retry) {
    config._retry = true

    try {
      // Request new token from server
      const authenticate = await instance.post('/user/login', {refresh_token: currentTokens.refresh_token})

      // Extract tokens and success status from authenticated request
      const { tokens, success } = authenticate.data

      // If successful, update access_token, id_token, headers and localStorage      
      if(success) {
        currentTokens.access_token = tokens.access_token
        currentTokens.id_token = tokens.id_token

        const bearer = `Bearer ${tokens.id_token}`
        config.headers['Authorization'] = bearer
        Object.assign(instance.defaults, {headers: {Authorization: bearer}})

        localStorage.setItem('tokens', JSON.stringify(currentTokens))

        // Retry original request
        return instance(config)
      }
    } catch (e) {
      // Handle any errors
      console.log(e)
      return
    }
  } else if(data && data.token_invalid !== undefined && data.token_invalid) {
    // Redirect user to ADFS for reauthentication if refresh has expired
    location = `${process.env.OAUTH_CLIENT_EP}?client_id=${process.env.AZURE_CLIENT_ID}&redirect_uri=${process.env.REDIRECT_URI}&resource=${process.env.REDIRECT_URI}&response_type=code`
    return
  } else {
    // Log all other errors
    return
  }
})

export default instance

Answer №1

After some investigation, I pinpointed the root cause of my issue. It seems that mixing relative and absolute URLs for the baseURL was causing a problem. While the absolute URL in development worked fine, the relative URL ended up appending to the original request.

To clarify, when sending a request in production, the URL appeared as /api/api/actual/request instead of just /api/actual/request.

To fix this, I introduced a new constant API_URL in my configuration files and set it to the absolute URL for both development and production environments. Then, I updated my instance creation code as shown below:

const instance = axios.create({
  baseURL: process.env.API_URL
})

I want to express my gratitude to everyone who took the time to view and offer suggestions. Wishing you all a fantastic day!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to display array values (using jQuery)

Help! I am having trouble rendering all my values. I have names (buttons) and when I click on them, I want to render the array behind it. Using .append() works, but the issue is that when I click again, it doesn't refresh and gets stacked. I am thinki ...

Expanding upon React Abstract Component using Typescript

Currently, I am in the process of building a library that contains presentations using React. To ensure consistency and structure, each presentation component needs to have specific attributes set. This led me to create a TypeScript file that can be extend ...

When implementing jQuery for scrolling on a website, touch gestures may become unresponsive on Safari for iOS devices

While developing a custom website with Angular, I encountered an issue specifically with Safari on iOS. The website is a single-page app with multiple menu sections that trigger a scroll animation when selected using jQuery. Everything was working smoothly ...

Exploring the images in a continuous loop

Looking to create a unique image looping effect using HTML, CSS, and Jquery/Javascript. The concept is to display several images on one page that do not move, but loop through them one at a time while displaying text above the current image. For example, ...

Using function arguments as private variables in JavaScript allows for better encapsulation

Have you ever wondered if function arguments automatically become private variables within the function? I came across this interesting concept and decided to experiment: var node = function(nParent,nName,nContent){ this.init = function(){ ale ...

Angular select element is not functioning properly with the `addEventListener` method

My current project involves creating a table using the primeng library. The table consists of three rows and three columns, and all the data is static. Even though I am utilizing an external library, I find myself traversing the DOM directly. <p-table ...

What is the best way to manage a hover effect on devices such as iPads?

As a beginner in web development, I am currently facing a challenge when it comes to managing hover effects on devices like iPads. Initially, my solution was to remove the CSS for hover and replace it with click events, but my client prefers to keep the ho ...

typescript unconventional syntax for object types

As I was going through the TypeScript handbook, I stumbled upon this example: interface Shape { color: string; } interface Square extends Shape { sideLength: number; } var square = <Square>{}; square.color = "blue"; square.sideLength = 10; ...

"Learn how to seamlessly submit a form without reloading the page and send data back to the same page using Node and Express

I've already reviewed a few questions on this platform. They all focus on submitting post requests, but I believe the process should be similar for get requests as well. Therefore, I made modifications to my code to accommodate get requests. However, ...

Assigning a custom class to the cdk-overlay-pane within a mat-select component is restricted to Angular Material version 10.2.7

I attempted the code below, but it only works for angular material 11. My requirement is to use only angular material 10. providers: [ { provide: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'customClass' } } ] There a ...

Is there a way for me to prevent the need to open a new window to view the results?

Can someone help me with my code? I want to display results without opening a new window or replacing the current content in the same window. I'm thinking of using AJAX to show results in a dialog window using JQueryUI but I'm not sure how to do ...

Tips on updating a JSON file exclusively using vanilla JavaScript with an AJAX call using the HTTP POST method?

Question One: I have been struggling to find a way to update a JSON file using the HTTP POST method when both files are stored on the same server (e.g. Godaddy or AWS). While I am able to send data to the server successfully, the JSON file is not being upd ...

Using jQuery to Save Data Locally in a JSON File

Just a heads up; all of my work is kept local. I've been on the hunt for ways to write to a JSON file from a JS script using jQuery. Many methods involve PHP, but I don't have much experience with that language and would prefer to avoid it for no ...

Steps for dynamically loading the content of a Bootstrap 4 Modal

I am currently in the process of developing a website that will showcase a wide range of images. The design is set up as a landing page with all content contained within the main HTML page - there is only an index.html file for now. This website will serv ...

Creating a custom directive in AngularJS that utilizes an event listener

I am currently working on designing a custom directive that includes a text box. When a user clicks a button, the text box should expand and become focused. If the user then clicks away from the expanded text box, it should minimize, disappear, and display ...

Using JQuery Slider to call a function without the need for an ID, instead utilizing the object directly

Currently, I am working on implementing a Slider using JQuery, and I have encountered an issue in my code. The function is set to run when the page loads, creating a slider with the Id specified in the div element: $(function() { $( "#slider& ...

Is it possible to verify the data within a VueJS model? It seems that none of the Vue validators are effective

Hello there, It's common knowledge that using Vue-validator with most UI components can be challenging when it comes to validation. I've been utilizing Vue Material Components by @mjanys, which is a fantastic library. The author has included met ...

What could be causing the failure of role.permissions.remove()?

I attempted to create a command that would remove the MENTION_EVERYONE permission from all roles, but it seems like it's not working as expected. While I was able to identify which roles have the permission through console logging, for some reason the ...

The jQuery .next() function is applying a class to each element

I am struggling with adding a class to the <a> elements in my Bootstrap 4 Carousel when the slider changes. Currently, my code successfully adds the class .highlight to the next <a> elements, but it adds it to all subsequent elements. Addition ...

Troubleshooting NodeJS with Socket.IO 1.0: Identifying Memory Leaks Beyond the Heap

We have encountered an issue while trying to deploy a small NodeJS app with Socket.IO. The problem arises when the total memory usage (rss) exceeds 2gb after approximately 2 hours, despite the heap size being within acceptable limits. To confirm that the ...