使用 axios.interceptors 获取新令牌

新手上路,请多包涵

当token过期的时候,我想根据refresh_token获取一个新的token。我读过这可以通过 axios.interceptors 获得。

请检查是否:

  • 我是否正确配置了 axios.interceptors?
  • 我是否将其放置在正确的位置,即 Items 类之上。
  • axios.interceptors.response 分配给 interceptor 变量。我应该如何处理这个变量?

除了“axios.interceptors”之外,我还需要获得一个新令牌。令牌的有效期为 24 小时。

  • 我是否必须等待 24 小时才能测试它是否有效,或者是否可以以不同的方式更快地进行测试?
  • 我应该把’client_id’、’secret_id’、’grant_type’放在哪里?

代码在这里: https ://stackblitz.com/edit/react-pkea41

 import axios from 'axios';

axios.defaults.baseURL = localStorage.getItem('domain');

const interceptor = axios.interceptors.response.use(
  response => response,
  error => {
      // Reject promise if usual error
      if (errorResponse.status !== 401) {
          return Promise.reject(error);
      }

      /*
       * When response code is 401, try to refresh the token.
       * Eject the interceptor so it doesn't loop in case
       * token refresh causes the 401 response
       */
      axios.interceptors.response.eject(interceptor);

      return axios.post('/api/refresh_token', {
          'refresh_token': JSON.parse(localStorage.getItem('token'))['refresh_token']
      }).then(response => {
          /*saveToken();*/
          localStorage.setItem('token', JSON.stringify(response.data));
          error.response.config.headers['Authorization'] = 'Bearer ' + response.data.access_token;
          return axios(error.response.config);
      }).catch(error => {
          /*destroyToken();*/
          localStorage.setItem('token', '');
          this.router.push('/login');
          return Promise.reject(error);
      }).finally(createAxiosResponseInterceptor);
  }
);

class Items extends Component {

  constructor (props) {
    super(props);
    this.state = {

    }
  }

  render () {
    return (
      <div >

      </div>
    )
  }
}

render(<Items />, document.getElementById('root'));

原文由 Umbro 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 277
2 个回答

请检查我是否正确配置了 axios.interceptors。

我认为它有效。但我建议你还是仔细测试一下。这是一篇很好的文章可以参考 https://blog.liplex.de/axios-interceptor-to-refresh-jwt-token-after-expiration/

我把它放在正确的地方了吗,即在 Items 类之上。 ?

您应该创建一个服务函数来包装 Axios 和 API 配置,当然还有拦截器

axios.interceptors.response 被分配给拦截器变量。我应该如何处理这个变量?

它只是一个用于定义拦截器的变量。别管它。如果你想避免分配它,只需在这样的函数中执行它 Automating access token refreshing via interceptors in axios

我必须等待 24 小时才能测试它是否有效,或者是否可以以不同的方式更快地进行测试?

您可以更改保存在 localStorage 中的令牌,然后执行此操作

我应该把’client_id’、’secret_id’、’grant_type’放在哪里?

如果将它存储在 localStorage 中,则页面中的任何脚本都可以访问它(这听起来很糟糕,因为 XSS 攻击可以让外部攻击者访问令牌)。

不要将其存储在本地存储(或会话存储)中。如果您包含在页面中的任何第 3 部分脚本遭到破坏,它可以访问您所有用户的令牌。

JWT 需要存储在 HttpOnly cookie 中,这是一种特殊的 cookie,它只在 HTTP 请求中发送到服务器,并且永远无法从浏览器中运行的 JavaScript 访问(无论是读取还是写入)。

原文由 Vu Luu 发布,翻译遵循 CC BY-SA 4.0 许可协议

这就是我之前所做的。你的配置和我的有点不同。

 const baseURL = localStorage.getItem('domain');
const defaultOptions = {
  baseURL,
  method: 'get',
  headers: {
    'Content-Type': 'application/json',
  }
};
// Create Instance
const axiosInstance = axios.create(defaultOptions);
// Get token from session
const accessToken = ...

// Set the auth token for any request
instance.interceptors.request.use(config => {
  config.headers.Authorization = accessToken ? `Bearer ${accessToken}` : '';
  return config;
});

// Last step: handle request error general case
instance.interceptors.response.use(
  response => response,
  error => {
    // Error
    const { config, response: { status } } = error;

    if (status === 401) {
      // Unauthorized request: maybe access token has expired!
      return refreshAccessToken(config);
    } else {
      return Promise.reject(error);
    }
  }
});

我认为这部分应该与 Components 分开——它将放在 helpers 或 utils 上。此外,您必须等待 24 小时,因为在 24 小时之前不会调用 refreshToken() 方法。你不需要处理 client_id , secret_id , grant_type 就在这里。

原文由 user11869519 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题