如果令牌已过期则注销

时间:2019-12-26 06:14:34

标签: javascript reactjs redux axios token

我正在处理一个包含许多API请求的React应用程序。该应用程序的结构是

登录时,我收到响应令牌,并将令牌保存在本地存储中以供其他API请求使用。

此令牌每30分钟过期一次,如果我在30分钟后发出API请求,则请求中的状态为401。我正在使用此401状态注销并清除本地存储中的令牌数据。

示例请求

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());
                }
              });
    }
}

所以要以这种方式注销,我必须对我使用的每个API(大约40个API)进行此检查。这是遵循的最佳方法还是有更好的方法来处理注销。我已经读过axios interceptors,但不清楚如何在系统中实现它。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

将此代码放在项目的初始化或加载部分中,然后运行一次 那么每次您调用axios时,此代码都会检查错误

在此处更改变量并使用

  // 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);
  });

答案 1 :(得分:0)

您可以为axios编写自己的包装,它应该是这样的:

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,
  });
};

因此它将在每个请求之前检查exprire_date并发送新请求以获取新令牌,以使用户不会注销

答案 2 :(得分:0)

是的,如果您不能使用刷新令牌(应该给予刷新令牌以理想地保持登录状态),则部分正确。

使用axios拦截器拦截响应,直到它变成需要处理的错误(如401)。

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);
  });