Vue eliminates the repeated prompt of refreshing the page when the token expires

Time:2022-5-14

1. Problem phenomenon

The page has not been operated for a long time. When refreshing the page again, the first pop-up “token is invalid, please log in again!” Prompt, then jump to the login page, and then pop up n back-end message prompts of “token expired”.

2. Cause analysis

During the initialization of the current page, there are multiple calls to query the system parameters from the back end. The code is as follows:

created () {
    // ========================================================================
    //Get the required system parameters. Note: getparameterclass method loads data asynchronously.
    //If you need to print observation, you need to process it through watch

    //Gets the parameter category of the user type
    this.commonFuncs.getParameterClass(this,"user_type","userTypeList","userTypeMap");

    //Get parameter category of user status
    for(var i = 0; i < this.userStatusList.length; i++){
      var item = this.userStatusList[i];
      var mapKey = parseInt(item.itemKey);
      this.userStatusMap.set(mapKey, item);
    }

    //Get parameter category of gender
    this.commonFuncs.getParameterClass(this,"gender","","genderMap");

    //Get parameter category of Department
    this.commonFuncs.getParameterClass(this,"department","","deptMap");

    //Gets the parameter category of the role
    this.commonFuncs.getParameterClass(this,"role","","roleMap");

    //Query user records
    this.queryUsers();
  },

These requests, called by Axios, are executed asynchronously, so they are issued almost immediately when the page is refreshed. Then, the responses to these requests will be returned one after another.

The response is first processed by the following response Interceptor:

//Response interceptor related to token
instance.interceptors.response.use(response => {  
  if (response) {
    switch (response.data.code) {
      Case 3: // token is empty
      Case 4: // token expired
      Case 5: // incorrect token    
        localStorage. clear();     // Delete user information
        Alert ('token is invalid, please login again! ');
        //To jump to the landing page
        router.replace({
              path: '/login',
        });
        break;
      Case 6: // access prohibited
        //Skip to page 403
        router.replace({
          path: '/forbidden',
        });        
        break;
      default:
        break;
    }
  }
  return response;
}, error => {
  return Promise. Reject (error. Response. Data. Message) // returns the error message returned by the interface
})

Then enter the code at the request call:

this.instance.getParameterClass(
      this.$baseUrl, {"classKey" : classKey}
    ).then(res => {
      //console.log(res.data);
      if (res.data.code == parent.global.SucessRequstCode){
        //If the query is successful
        //Successful processing code
      }else{
        alert(res.data.message);
      }
    }).catch(error => {
      //Alert ('failed to query system parameters! ');            
      console.log(error);
    });

The question now:

  1. Corresponding to a request, if the token expires, the reponse interceptor will first pop up an alarm prompt, and then there will be a prompt at the call:

    alert(res.data.message);

    This is repeated.

  2. For multiple requests sent at the same time, a mark is required to remember whether the token expiration has been prompted. It is only prompted once. If it has been prompted, there is no need to prompt again.

3. Solution

3.1. Eliminate the repeated prompt of token expiration at the interceptor and request call

Write a public method to check whether it is the return code of intercepted processing, and put it in / SRC / common / CommonFunctions JS file, the code is as follows:

/**
   *The return code to judge whether it is intercepted. If true is returned, it means it is intercepted
   *The function of this method is to call without handling the error prompt of the intercepted return code
   *@ param {return code of request} code 
   */
  isInterceptorCode(code){
    switch (code) {
      Case 3: // token is empty
      Case 4: // token expired
      Case 5: // incorrect token    
      Case 6: // access prohibited
        return true;
      default:
        break;
    }
    return false;
  }

Then, the processing of all calls for unsuccessful returns is changed to:

if (!this.commonFuncs.isInterceptorCode(res.data.code)){
          alert(res.data.message);
        }

In this way, the repeated alarm of interception processing and call processing is eliminated.

3.2. Processing of multiple requests prompted only once

In the global variable file / SRC / common / global JS, add the token invalid flag, and the code is as follows:

//Global variable

export default {
  //Request success return code
  SucessRequstCode:0,

  //Token invalid token
  TokenInvalidFlag : 0
}

Then, modify the interceptor Code:

//Response interceptor related to token
instance.interceptors.response.use(response => {  
  if (response) {
    switch (response.data.code) {
      Case 0: // normal
        //Reset token invalid flag
        global.TokenInvalidFlag = 0;
        break;            
      Case 3: // token is empty
      Case 4: // token expired
      Case 5: // incorrect token    
        if (global.TokenInvalidFlag == 0){
          //Delete user information
          localStorage.clear();  
          //Alarm prompt   
          Alert ('token is invalid, please login again! ');
          //The token is invalid. The token is set to 1
          global.TokenInvalidFlag = 1;
          //To jump to the landing page
          router.replace({
                path: '/login',
          });
        break;
      Case 6: // access prohibited
        //Skip to page 403
        router.replace({
          path: '/forbidden',
        });        
        break;
      default:
        break;
    }
  }
  return response;
}, error => {
  return Promise. Reject (error. Response. Data. Message) // returns the error message returned by the interface
})

That is, when the token expiration message is received for the first time (at this time, tokeninvalidflag = 0), it will be prompted, and then set to 1 (at this time, tokeninvalidflag = 1). The responses of subsequent requests will not be prompted in the alarm. Until the successful return code is received, it is reset to 0, which indicates that the login is successful.

After testing, this treatment achieves the expected effect, that is, when the token expires, refresh the page and only prompt an alarm once.

Recommended Today

Extcon driver and its application in USB driver

Extcon, short for external connector, is used to abstract external connectors, such as audio jack, USB microb / typec interface, etc. Its prototype is the switch class driver of Android. After modification, it was introduced into the kernel in kernel version 3.4.0. Extcon (external connector): import Android’s switch class and modify. External connector class (extcon) is based on and an extension of Android kernel’s switch class located at linux/drivers/switch/. https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/extcon?h=next-20220502&id=de55d8716ac50a356cea736c29bb7db5ac3d0190 The main function of extcon driver is to identify the […]