axios token authority authentication request mechanism, and the front end realizes senseless refresh

Keywords: Javascript React Ajax

axios token authority authentication request mechanism

Detailed explanation of parameter attributes

Mechanism process

1. Login

The user enters the account and password to log in. After successful login, save the user information, token and other information to the local localstorage.

2. Add request header to global axios

When importing the global axios file, the information has been stored in localstorage when logging in. Therefore, it is detected when importing. If there is a token value, the request header will be configured globally for axios (if there are multiple axios objects, the request headers will be configured respectively).

3. Add interceptors to global requests

After the second step is completed, the request axios in all global pages have been configured with request headers and can request data normally. In order to achieve the effect of token insensitive refresh, the implementation logic is:

During page switching, several requests are bound to be initiated. An interceptor is added before each request to judge how long the current token is left from the expiration time. If the time period is between 0-10 minutes (10 minutes is just an example, which means that the token will be refreshed 10 minutes in advance when it is about to expire), then a request will be initiated to refresh the token in advance to avoid 401 errors caused by expired tokens on the interface when it expires, so as to achieve the effect of refreshing the token senselessly.

So add the interceptor before the request to the axios Global:

// Get local token
const getToken = () => {
  let token;
  try {
    token = JSON.parse(localStorage.getItem("userData"));
  } catch (e) {
    message.error(e);
    return;
  }
  return token;
};

axios.interceptors.request.use(res => {
  beforeAxios()
  return res
})

const beforeAxios = () => {
  if(token && !tokenIsRefresh) {
    const time = token.expires - Date.now()
    if (time < 0) {
      message.error('Login information is invalid, please login again!')
      localStorage.removeItem('userData')
      window.location.href = '/'
    } else if(time < validTime && time > 0) {
      // console.log('insensitive refresh ')
      tokenIsRefresh = true
      refresh(token.refresh_token);
    }
  }
}
4. Add processor to global request

Since the interceptor is added before the axios global request, it is also necessary to add processing after the axios global request: if the request result is empty, or the authentication fails due to the token problem, and the request fails, return the user to the login page for re login:

axios.interceptors.response.use((res) => {
  if (res.data.code === 401 || res.code === 401) {
    message.error(res.data.message);
    localStorage.removeItem('userData')
    window.location.href = '/'
  } else if (res.data.code === 500) {
    message.error(res.data.message);
  }
  return res;
},
(err) => {
  errorHandler(err);
});

const errorHandler = (err) => {
  err && process.env.NODE_ENV == "development" && console.error(err);
  const newErr = err.toString()
  if (newErr.substring(newErr.length - 3) === '401') {
    message.error("Login information is invalid, please login again!",1);
    setTimeout(() => {
      localStorage.removeItem('userData')
      window.location.href = '/'
    },1000);
  } else if (newErr.substring(newErr.length - 3) === '403') {
    message.error('Insufficient permissions')
  }
  else {
    // message.error('Please login again ')
    // localStorage.removeItem("token");
    // setTimeout(() => (window.location.href = "/"), 500);
  }
};

So far, in fact, a complete set of logic about axios requesting token has been completed. It involves token storage, expiration processing and insensitive refresh.

5. Other circumstances

In the actual development, you can also consider a situation: if the user accidentally goes to the console to empty all the contents in the localstorage, the system detects that if the token related information in the original localstorage is cleared, the user will be automatically kicked back to the login interface and asked to log in again. The specific implementation code is as follows:

// Get local token
const getToken = () => {
  let token;
  try {
    token = JSON.parse(localStorage.getItem("userData"));
  } catch (e) {
    message.error(e);
    return;
  }
  return token;
};

window.addEventListener("storage", (e) => {
  process.env.NODE_ENV == "development" && console.log(e.key, e.newValue, e.oldValue);
  // If userData is cleared in the console
  if(!getToken()) {
    message.error("Login information is invalid, please login again!",1);
    setTimeout(() => {
      localStorage.removeItem('userData')
      window.location.href = '/'
    },1000);
  }
});

In addition, users may log in on one page and then go to another page of the project (such as the main interface and background management interface). Similarly, you can configure axios in the main interface according to the above steps. All the implementation codes will not be posted, because the specific fields of different login interfaces may be different, but the implementation logic can be referred to.

Posted by deljhp on Fri, 24 Sep 2021 00:49:17 -0700