node.jsreactjsauthenticationjwthttp-status-code-401

using refresh token to get new access token react and node js


I've built a JWT API for user authentication. I want to use it with react. my app has these routes:

Node js API Routes:

React Client Routes:

when I log in to my website I can see the data inside the user route for 20 seconds before the access token expiry. when the access token is expired and I do a new request the server will response with 401 unauthorized code. so this way I can make sure that the access token is expired and I need to use refresh token. I've done that like this:

const API_URL = "http://localhost:8080/api/test/";

const getUserBoard = () => {
  return axios.get(API_URL + "user", { headers: authHeader() })
            .catch((error) => {
              if(error.response.status === 401) {
                // if error response status was 401 then request a new token
                authService.refreshToken();
                window.location.reload();
              }else if(error.response.status === 403) {
                authService.logout();
                window.location.href = "/login";
              }
            });
};

code to get new access token with refresh token:

const refreshToken = () => {
  axios({
    url: API_URL + "refreshtoken",
    method: "POST",
    withCredentials: true
  })
    .then((response) => {
      if(response.data.accessToken) {
        const user = JSON.parse(localStorage.getItem("user"));
        user.accessToken = response.data.accessToken;
        localStorage.setItem("user", JSON.stringify(user));
      }
    })
    .catch((error) => {
      console.log("server: " + JSON.stringify(error.response));
    })
}

code to set header for receiving data from server using access token:

export default function authHeader() {
    const user = JSON.parse(localStorage.getItem('user'));
  
    if (user && user.accessToken) {
      // for Node.js Express back-end
      return { 'x-access-token': user.accessToken };
    } else {
      return {};
    }
}  

the first part for getting new access token on 401 error works good but my refresh token also expires after 40 second. if I send the expired refresh token it won't return a new access token. and because of that again I will receive a 401 error which again will cause a 403 error and here I'll get stuck in an infinite reload loop.

any idea? how can I control tokens expiry?


Solution

  • You're issuing tokens in your node.js app, right? So that is where you should adjust the expiration time of the token. The code which issue tokens should have an option to set the expiration time.

    Remember that once the refresh token is expired you should log in again. You can implement something which is called a rolling refresh token. So whenever you call the /api/auth/refreshtoken endpoint you can also issue a new refresh token, with a new expiration time and return it in a cookie.