保存后存储令牌身份验证

时间:2019-06-25 08:01:58

标签: javascript vue.js axios unauthorized

我创建了文件JS以从数据库获取令牌并将其保存在会话存储中,然后将该文件导入Vue中的app.js:

import Auth from './auth/auth';

new Vue({
    el: "#app_resource",
    router,
    store,
    beforeMount() {
      window.auth = new Auth();
    },
    render: h => h(App)
});

文件auth.js

import axios from 'axios';

class Auth  {
  constructor() {
    this.getToken();
    let token = window.sessionStorage.getItem('token');
    if (token) {
      axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
    }  
  }

  getToken(){
    let options = {
      method: "post",
      url: "/getapitoken",
      headers: {
          'Accept': 'application/json'
      }
    };
    axios(options)
    .then(response => {
      let token = response.data.token
      if (token) {
        this.issetToken(token);
      }
    })
    .catch(({ response }) => {
      console.warn(response); 
    });
  }

  issetToken(token){
    if (window.sessionStorage.getItem('token') === null) {
      window.sessionStorage.setItem('token', token);
    } else {
      window.sessionStorage.removeItem('token');
      window.sessionStorage.setItem('token', token);
    }
    axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
  }

}

export default Auth;

会话存储中的令牌可以正确保存,但是我有一个问题,因为登录后我已重定向到起始页面,起始页面上的是从数据库中获取数据,并且我需要令牌来获取此数据。但是Vue返回错误401(未授权)(例如Vue无法看到令牌)。 我必须刷新页面,现在我可以从数据库获取数据了。

如何在登录后不刷新页面的情况下获取日期?

1 个答案:

答案 0 :(得分:0)

我认为,问题在于您在其他地方提出请求时正在获取令牌。

这是我相信事情正在发生的顺序。

  • auth.js构造函数启动获取令牌的请求
  • auth.js将存储中的令牌(首次加载时丢失)分配给默认令牌
  • somecomponent.vue使用丢失的令牌(会话为空)进行api调用
  • auth.js完成getToken并将新令牌分配给默认标头
  • somecomponent.vue的api调用失败,因为该API调用没有令牌

现在,当您刷新页面时...

  • auth.js构造函数启动获取令牌的请求
  • auth.js从存储分配令牌
  • somecomponent.vue使用会话存储中的令牌进行api调用
  • auth.js完成getToken并更新会话中的令牌
  • somecomponent.vue的api调用成功,因为该API调用在getToken函数获得新的令牌之前使用了正确的令牌

在这种情况下,您需要做的就是将所有api活动推迟到拥有令牌之前。当然,这可能并非一帆风顺,因为您需要知道是否设置了令牌,并链接请求或有某种方法。

您可以尝试通过使函数返回承诺来阻止重定向,直到getToken成功(尽管我不知道您如何处理)

  getToken(){
    let options = {
      method: "post",
      url: "/getapitoken",
      headers: {
        'Accept': 'application/json'
      }
    };
    return axios(options)
    .then(response => {
      let token = response.data.token
      if (token) {
        this.issetToken(token);
        return token;
      }
    })
    .catch(({ response }) => {
      console.warn(response); 
    });
  }

然后您可以使用window.auth.getToken().then(()=>doMyRedirect())

之类的东西

我过去处理这些情况的方式是使用Vuex,并且在Vuex存储中保留状态信息,因此任何其他函数都可以检查令牌是否正在被提取,因此不会同时发出其他请求,但这仍然需要一些逻辑才能使请求在之后发生。