首页 > 解决方案 > Axios 拦截器未从 vuex 商店获取当前用户身份验证令牌

问题描述

我正在使用 Axios 将用户输入发送到 DRF api,它返回一个身份验证令牌。我将令牌保存在 vuex 商店中。在另一个组件中。我正在尝试使用 Axios 请求另一个 api 端点,并在请求标头中使用最新的令牌。我遇到的问题是 Axios 将发送完全没有令牌的请求,或者使用之前登录用户的令牌发送请求。它不会从 vuex 存储中获取当前令牌。我使用 Axios 拦截器希望这会有所帮助,但它没有。

登录.vue

<script>

export default {
  name: 'Login',
  data () {
    return{
      email: null,
      password: null,

      token: '',

    }
    
  },
  props: {
    
  },

  methods: {
    submitForm () {

      this.$store.dispatch('loginUser',{
        email: this.email,
        password: this.password
      }).then(() =>{
        this.$router.push({ name: 'List' })

      }) .catch(err =>{
        console.log(err)
      })
      
    },

  }


}
</script>

存储/index.js

import axios from 'axios'
import { createStore } from 'vuex'


export default createStore({
  state: {
    token: localStorage.getItem('token'),
  },
  mutations: {
    getToken(state, token) {
      localStorage.setItem('token', token)
      state.token = token
      
      
    }
  },
  actions: {
    loginUser({ commit }, data){
      axios({
        method: 'POST',
        url: 'http://localhost:8000/auth/login/',
        headers: {'Content-Type': 'application/json'},
        data: {
          'email': data.email,
          'password': data.password,
        }
      }).then(response =>{
        commit('getToken', response.data['key'])
      })
    }
  },
  modules: {
  }
})

列表.vue

<script>
import axios from 'axios'
import store from '/src/store'
export default {
    name:'List',
    data () {
        return {
            entry: []
        }
    },

    created() {
        axios.interceptors.request.use(function (config){
            let token = store.state.token
            config.headers['Authorization'] = 'Token ' + token;
            return config;
        })
        axios({
        method: 'GET',
        url: 'http://localhost:8000/journal/',
        headers: {'Content-Type': 'application/json'},
        
      }).then(response =>{

          this.entry = response.data


        
      }) .catch(err =>{
          console.log(err)
      })
    }
}
</script>

我认为拦截器的目的是在实际发出获取请求之前获取令牌,但它似乎没有这样做。

标签: vue.jsdjango-rest-frameworkaxios

解决方案


不完全确定为什么会这样,但是像这样重写我的 loginUser 操作可以解决我的问题。

actions: {
    loginUser({ commit }, data){
      return new Promise ((resolve, reject) => {

      
      axios({
        method: 'POST',
        url: 'http://localhost:8000/auth/login/',
        headers: {'Content-Type': 'application/json'},
        data: {
          'email': data.email,
          'password': data.password,
        }
      }).then(response =>{
        commit('getToken', response.data['key'])
        resolve()
      }).catch(err => {
        reject(err)
      })
    })
    }
  },

我认为这是因为 return new Promise 基本上会中断 Login.vue 中的初始承诺,以确保客户端在没有来自服务器的正确令牌的情况下不会发出 api 请求,但我不确定。


推荐阅读