Axios实例Bearer令牌在登录后不重新加载时未更新 – React

huangapple go评论58阅读模式
英文:

Axios Instance Bearer token not updated after login without reloading - React

问题

当我尝试登录到我的React应用时,它返回成功并将其保存在sessionStorage中,但当我尝试访问需要Bearer令牌通过axios获取数据的页面时,返回http 401错误。

但是当我重新加载页面,然后结果就是所需的。

import axios from "axios";

let token = JSON.parse(window.sessionStorage.getItem("token"));

let AxiosInstance = axios.create({
  baseURL: "https://myurl.com/backend/api/",
  timeout: 5000,
  headers: { Authorization: "Bearer " + token },
});

export default AxiosInstance;
英文:

When I try to login to my react app it returns as success and saves it in sessionStorage but when I try to access the page which requires Bearer token to fetch data via axios it returns http 401 error.

But when I reload the page, then the result is as required.

import axios from "axios";

let token = JSON.parse(window.sessionStorage.getItem("token"));

let AxiosInstance= axios.create({
  baseURL: "https://myurl.com/backend/api/",
  timeout: 5000,
  headers: { Authorization: "Bearer " + token },
});

export default AxiosInstance;

答案1

得分: 6

我猜这是因为你在 React 的生命周期之外创建了 axios 实例。

当你运行应用并进入登录界面时,会创建一个 Axios 实例:

import axios from "axios";

let token = JSON.parse(window.sessionStorage.getItem("token"));

let AxiosInstance = axios.create({
  baseURL: "https://myurl.com/backend/api/",
  timeout: 5000,
  headers: { Authorization: "Bearer " + token }, // 在第一次运行时,token 为 null
});

export default AxiosInstance;

登录后,你的 axios 实例仍然具有一个 null 的 token。这段代码只会执行一次,所以当你刷新页面时,它能够工作,因为当这段代码再次执行时,本地存储中会有一个 token。

有几种方法可以解决这个问题,但我认为最简单的方法是使用 Axios 拦截器:

AxiosInstace.interceptors.request.use(function (config) {
  const token = localStorage.getItem('token');
  config.headers.Authorization = token ? `Bearer ${token}` : '';
  return config;
});

这样每次发送请求时你的 headers 将会被更新(不确定这是否是最佳方法,但是它有效)。

英文:

I'll guess it is because you're creating the axios instance outside any of React's lifecycle

when you run your app and enter your login screen, it makes a Axios instance

import axios from "axios";

let token = JSON.parse(window.sessionStorage.getItem("token"));

let AxiosInstance = axios.create({
  baseURL: "https://myurl.com/backend/api/",
  timeout: 5000,
  headers: { Authorization: "Bearer " + token }, // on the first go token is null
});

export default AxiosInstance;

After you login, your axios instance still has a nulll token, you see, this code is executed once and never more, that's why when you refresh the page, it works, because when this piece of code is executed once again, there's a token in localstorage.

There's a couple things you can do but the easiest i guess it's to use Axios interceptors

  AxiosInstace.interceptors.request.use(function (config) {
    const token = localStorage.getItem('token');
    config.headers.Authorization =  token ? `Bearer ${token}` : '';
    return config;
  });

That way every time you do a request your headers will be updated (not sure if this is the best approach but it works)

答案2

得分: 2

你的`token`在`onload`时初始化,所以你必须在每次通过`拦截器`发送请求时调用`config.headers["Authorization"]`中的token,这样你就不需要重新加载页面。

__拦截器:__
Axios拦截器是在发送请求之前和收到响应之后调用的函数。

import axios from "axios";

let AxiosInstance = axios.create({
baseURL: "https://myurl.com/backend/api/",
timeout: 5000,
});

AxiosInstance.interceptors.request.use(function (config) {
let token = JSON.parse(window.sessionStorage.getItem("sessionData"));
config.headers["Authorization"] = "Bearer " + token;
return config;
});

export default AxiosInstance;


__更新:__ 您可以在[这里][1]了解更多关于Axios拦截器的信息。

  [1]: https://axios-http.com/docs/interceptors
英文:

Your token is being initialized onload so you have to call token in config.headers["Authorization"] on every request through interceptor so you don't need to reload page.

Interceptor:
Axios interceptors are functions that are called before a request is sent and after a response is received

import axios from "axios";

let AxiosInstance = axios.create({
  baseURL: "https://myurl.com/backend/api/",
  timeout: 5000,
});

AxiosInstance.interceptors.request.use(function (config) {
  let token = JSON.parse(window.sessionStorage.getItem("sessionData"));
  config.headers["Authorization"] = "Bearer " + token;
  return config;
});

export default AxiosInstance;

UPDATE: You can learn more here about Axios interceptors

huangapple
  • 本文由 发表于 2023年2月8日 19:52:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定