【问题标题】:localStorage item not updating in axios headerslocalStorage 项目未在 axios 标头中更新
【发布时间】:2018-05-22 18:20:08
【问题描述】:

我正在使用 JWT 令牌认证系统,当我登录时,我会得到这样的令牌:

axios.post('/login', data)
    .then(response => {
        localStorage.setItem('token', response.data.token);
   });

这很好用,令牌保存在 localStorage 中。但是,令牌不包含在以后的请求中。 Authorization 标头是Bearer null

这就是我设置全局 axios 对象的方式。

window.axios = axios.create({
    baseURL: '/api/',
    timeout: 10000,
    headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
        'Authorization': 'Bearer ' + localStorage.getItem('token')
    }
});

如果我刷新网站,token 已设置,并且可以正确使用。

编辑:

我通过从create() 方法中删除Authorization 标头并改用window.axios.defaults.headers.common['Authorization'] 来使其工作。但是现在 Laravel Echo 出现了同样的问题。我这样创建实例:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'xxx',
    cluster: 'eu',
    encrypted: true,
    namespace: 'xxx',
    auth: {
        headers: {
            'Authorization': 'Bearer ' + localStorage.getItem('token')
        }
    }
});

我像这样更新标题:

window.setAuthToken = (token) => {
    window.axios.defaults.headers.Authorization = 'Bearer ' + token;
    window.Echo.options.auth.headers.Authorization = 'Bearer ' + token;
    localStorage.setItem('token', token);
}

axios 标头更新成功,但 Echo 没有更新。

【问题讨论】:

  • 请检查答案。我还没有测试过,但它应该可以工作。
  • 查看更新的答案。

标签: javascript axios


【解决方案1】:

为此目的使用 axios interceptors。它会在每次请求调用时运行。

最好将 axios 方法保存在单独的文件中并调用它,而不是直接在所有组件中使用它。这样,如果我们愿意,我们可以用最小的努力将 axios 替换为另一个库。这是我在我的项目中所做的。

import axios from "axios";
import AuthService from "./auth";

import config from '../config'

const instance = axios.create({
  baseURL: config.apiServer.url,
  timeout: config.apiServer.timeout
});

instance.interceptors.request.use(
  config => {
    const token = AuthService.getToken();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => Promise.reject(error)
);

const ApiService = {

  get(url) {
    return instance.get(url)
      .then(res => res)
      .catch(reason => Promise.reject(reason));
  },

  post(url, data) {
    return instance.post(url, data)
      .then(res => res)
      .catch(reason => Promise.reject(reason));
  },

  awaitAll() {
    return axios.all(Array.from(arguments))
      .then(axios.spread((...responses) => responses))
      .catch(reasons => Promise.reject(reasons));
  }

};

export default ApiService;

现在在组件中使用它:

ApiService.get(YOUR_GET_URL)
      .then(res => {
        Console.log(res);
      ))
      .catch(reason => {
        console.log(reason);
      })

【讨论】:

    【解决方案2】:

    问题是您在页面加载时使用localStorage.getItem('token')。当你在localStorage中设置时,你必须在axios header中更新它。

    window.axios = axios.create({
        baseURL: '/api/',
        timeout: 10000,
        headers: {
            'X-Requested-With': 'XMLHttpRequest',
            'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
            'Authorization': 'Bearer ' + localStorage.getItem('token')
        }
    });
    
    axios.post('/login', data)
        .then(response => {
            localStorage.setItem('token', response.data.token);
            window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token');
        });
    

    【讨论】:

    • 这听起来合乎逻辑,但实际上似乎不起作用。令牌仍然是null
    • 你能创建一个最小的 fiddler/plunker 链接吗?
    • 好吧,如果我将其设置为“Authorization_foo”,则似乎设置了标题。那么,也许是 defaults 被覆盖了?
    • 我通过从create() 方法中删除Authorization 标头并改用window.axios.defaults.headers.common['Authorization'] 来使其工作。但是,现在我基本上对 Laravel Echo 有同样的问题。请参阅有问题的编辑。
    • 感谢兄弟拯救了我的一天,表扬了!
    【解决方案3】:

    我之前遇到过同样的问题,我发现包含我的 axios 配置的文件在存储令牌时正在加载,所以它在存储之前就在访问它。

    解决方案是,在 axios 配置中:

      const axiosInstance = axios.create({
      baseURL: `${API_BASE_URL}`,
      headers: {
        Accepted: 'appication/json',
        'Content-Type': 'application/json',
      },
    });
    
    axiosInstance.interceptors.request.use(
      (config) => {
        const token = localStorage.getItem('token');
        if (token) {
          config.headers.authorization = token;
        }
        return config;
      },
      (error) => Promise.reject(error),
    );
    
    export default axiosInstance;
    

    之后,在需要发出请求的地方使用此实例。

    【讨论】:

      猜你喜欢
      • 2016-08-31
      • 1970-01-01
      • 2023-01-08
      • 2021-04-09
      • 1970-01-01
      • 2020-03-27
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多