Logout if token is expired

99封情书 提交于 2020-01-30 08:19:30

问题


I'm working on a react application that consists of many API requests. The structure of the application is

When logging in, I'm receiving a token on response and I'm saving the token in my local storage to be used in other API requests.

This token is expired every 30 minutes and if I do an API request after 30 minutes, I'm receiving a status of 401 in my request. I'm using this 401 status to do my logging out and clearing token data in local storage.

Example request

export function stationDailyUsage(data) {
    return dispatch => {
        dispatch(dailyUsageLoading());
        axios.get(`${API_URL}/Dashboard/DailyUsage?type=${data.type}&date=${data.date}`, {
            headers: {
                'Authorization': `Bearer ${token}`
            },
        })
            .then(res => {
                if (res.data.success === true) {
                    dispatch(dailyUsageSuccess(res.data));
                } else {
                    console.log("error");
                }
            })
            .catch(function (error) {
                if(error.response.status === 401){
                    dispatch(logout());
                }
              });
    }
}

So to logout this way I have to do this check for every API I use (Around 40 APIs ). Is this the best approach to follow or is there a better way to handle the logout. I've read about axios interceptors but was not clear about how to implement it in my system. Any help is greatly appreciated.


回答1:


Put this code in your project initialize or loading section, and run it once then every time you call axios this code will check errors

Change your variable here and use it

  // Add a request interceptor
  axios.interceptors.request.use((config) => {
    let token = localStorage.getItem("token");
    if (token) {
      config.headers.credentials = 'include';
      config.headers.Authorization = `Bearer ${token}`;
      config.headers['Access-Control-Allow-Origin'] = '*';
      config.headers['Content-Type'] = 'application/json';
    }

    return config;
  }, (error) => {
    alert('interceptor request has error');
    return Promise.reject(error);
  });

  // Add a response interceptor
  axios.interceptors.response.use((response) => {
    return response;
  }, (error) => {

    if (error.response && error.response.data && error.response.data.error &&
      (error.response.data.session === false || error.response.data.session === "false")) {
      localStorage.removeItem("userId"); // <-- add your var
      window.location = "/";   // <-- add your path
    }
    else if (error.response && error.response.data && error.response.data.error && error.response.data.error.message) {
      toastMessage(error.response.data.error.message, 1);
    }
    else
      if (error.response && error.response.status === 401) {
        localStorage.removeItem("userId"); // <-- add your var
        window.location = "/";  // <-- add your path
      } else
        return Promise.reject(error);
  });



回答2:


Yes you're partially correct, in case you cannot use refresh tokens (which should be given to maintain the login state ideally).

Use axios interceptors to intercept the response before it becomes an error like 401 which needs to be handled.

axios.interceptors.response.use(function (response) {
    // 200 type responses, this should be left as it is
    return response;
  }, function (error) {
    // Handle your 401 error, maybe the UI changes and removing from local storage
    return Promise.reject(error);
  });



回答3:


You can write your own wrapper for the axios and it should be something like this:

import axios from 'axios';

const request = axios.create({
  baseURL: backUrl,
  timeout: 5000,
});

export const get = url => {
  const expiresIn = localStorage.getItem('expiresIn');
  const accessToken = localStorage.getItem('accessToken');

  if (expiresIn && Date.now() > expiresIn) {
    const refreshToken = localStorage.getItem('refreshToken');
    request
      .post('/oauth/token', {
        grant_type: 'refresh_token',
        refresh_token: refreshToken,
      })
      .then(res => {
        store.dispatch(
          loginSubmitted(
            res.data.access_token,
            res.data.refresh_token,
            res.data.expires_in,
          ),
        );

        localStorage.setItem('accessToken', res.data.access_token);
        localStorage.setItem('refreshToken', res.data.refresh_token);
        localStorage.setItem('expiresIn', res.data.expires_in);

        return request.get(url, {
          headers: { Authorization: `bearer ${res.data.access_token}` },
          accessToken: res.data.access_token,
        });
      })
      .catch(err => {
        localStorage.removeItem('accessToken');
        localStorage.removeItem('refreshToken');
        localStorage.removeItem('expiresIn');
      });
  }

  return request.get(url, {
    headers: { Authorization: `bearer ${accessToken}` },
    accessToken,
  });
};

so it will check the exprire_date before each request and send a new request for a new token so user won't log out



来源:https://stackoverflow.com/questions/59484512/logout-if-token-is-expired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!