0

In ReactJS project, I setup a global Axios interceptor to handle 401 error and redirect to the login page. This is working as expected if the server returns 401 error.

//global interceptor for handling 401 (invalid token) response.
axios.interceptors.response.use(
  function (response) {
    console.log("Axios defaut interceptor");
    return response;
  },
  function (error) {
    if (401 === error.response.status) {
      alert(
        "Your session has expired. You will be redirected to the login page."
      );
      window.location = "/login";
    } else {
      return Promise.reject(error);
    }
  }
);

The problem is that multiple GET requests are sent from the main page Class component's constructor() method. This causes the alert message to be shown multiple times.

What is the best way to handle the error and redirect to the login page only once?

Shankar
  • 2,625
  • 3
  • 25
  • 49

1 Answers1

0

The solution was to verify that a token is present before loading the page.

I was using Router to load the main page:

<Router basename={"/home"}>
    <Switch>
    <AuthenticateRoute
       path="/"
       exact={true}
       component={<Main component - change this>}
/></Router>

In the AuthenticateRoute component, verify that there is a token with valid expiry date.

class AuthenticatedRoute extends Component {
    render() {
       var isValidToken = false;
       const token = localStorage.getItem(USER_TOKEN);
       if (token === null) isValidToken = false;
       var decodedToken = jwt.decode(token, { complete: true });
       if (decodedToken.payload === null) isValidToken = false;
       //Get the current time in seconds.
       var dateNow = new Date();
       var nowDateSeconds = parseInt(dateNow.getTime() / 1000);
       //Check if token expiry time greater than current time (valid token)
       if (decodedToken.payload.exp > nowDateSeconds) {
            isValidToken = true;
       }
       if (isValidToken ) {
            return <Route {...this.props} />
        } else {
            return <Redirect to="/login" /> 
        }

    }
}

This was the main page will not be loaded if token is not valid. Note: This code does not authorize/authenticate the token. It just checks if a valid dated token is present, before loading the main component.

More details on JWT token validation in the browser here - React - How to check if JWT is valid before sending a post request?

Shankar
  • 2,625
  • 3
  • 25
  • 49