【问题标题】:Vuex Axios Token UndefinedVuex Axios 代币未定义
【发布时间】:2019-03-31 15:30:12
【问题描述】:

我正在尝试使用 Vuejs 和 Django 执行用户登录。我使用 vuex 和 django restframework 作为组件。当我在 Vuex 商店中使用用户登录表单时,django 会为用户创建令牌。但是,vue js 并没有检测到生成的用户令牌。令牌返回未定义。

我的 store.js 代码

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        status: '',
        token: localStorage.getItem('token') || '',
        user : {}
    },
    mutations: {
        auth_request(state){
            state.status = 'loading'
        },
        auth_success(state, token, user){
            state.status = 'success'
            state.token = token
            state.user = user
        },
        auth_error(state){
            state.status = 'error'
        },
        logout(state){
            state.status = ''
            state.token = ''
        },
    },
    actions: {
        login({commit}, user){
            return new Promise((resolve, reject) => {
                commit('auth_request')
                axios({url: 'http://localhost:8001/api/v1/token/create', data: user, method: 'POST' })
                .then(resp => {
                    const token = resp.data.token
                    const user = resp.data.user
                    localStorage.setItem('token', token)
                    // Add the following line:
                    axios.defaults.headers.common['Authorization'] = 'Bearer ${token}'
                    commit('auth_success', token, user)
                    resolve(resp)
                })
                .catch(err => {
                    commit('auth_error')
                    localStorage.removeItem('token')
                    reject(err)
                })
            })
        },
        register({commit}, user){
            return new Promise((resolve, reject) => {
                commit('auth_request')
                axios({url: 'http://localhost:8001/api/v1/users/create', data: user, method: 'POST' })
                .then(resp => {
                    const token = resp.data.token
                    const user = resp.data.user
                    localStorage.setItem('token', token)
                    // Add the following line:
                    axios.defaults.headers.common['Authorization'] = 'Bearer ${token}'
                    commit('auth_success', token, user)
                    resolve(resp)
                })
                .catch(err => {
                    commit('auth_error', err)
                    localStorage.removeItem('token')
                    reject(err)
                })
            })
        },
        logout({commit}){
            return new Promise((resolve, reject) => {
                commit('logout')
                localStorage.removeItem('token')
                delete axios.defaults.headers.common['Authorization']
                resolve()
            })
        }
    },
    getters : {
      isLoggedIn: state => !!state.token,
      authStatus: state => state.status,
    }
})

Main.js

...
import store from './store';
import Axios from 'axios';

Vue.prototype.$http = Axios;
const token = localStorage.getItem('token')
if (token) {
  Vue.prototype.$http.defaults.headers.common['Authorization'] = 'Bearer ' + token
}
...

登录页面

...
  data() {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login: function() {
      let username = this.username
      let password = this.password
      this.$store.dispatch('login', { username, password })
      .then(() => this.$router.push('/'))
      .catch(err => console.log(err))
    }
  }
...

【问题讨论】:

  • “Vue 未检测到生成的用户令牌”是什么意思?您是否确认令牌在登录响应中?登录后什么时候在 Vue 中读取令牌?
  • 嗨,你发现了吗?有同样的问题。
  • 我有同样的问题,但不是针对令牌,而是针对用户。

标签: vue.js django-rest-framework axios vuex


【解决方案1】:

您的 main.js 在 store.js 之前运行。只有在 store.js 中调用登录操作后才会生成令牌。之后没有任何事情会再次触发localStorage.getItem() 方法,因此该标记仍然未定义。

获取令牌最简单的方法是在 getters 中为令牌添加另一个条目,然后使用 mapGetters 从您想要的任何组件中获取它。

【讨论】:

    【解决方案2】:

    如果有人碰到它:

    我让它调用了一些私人助手:

    function setDefaultAuthHeaders(state) {
        axios.defaults.headers.common.Authorization = state.currentToken
           ? `Bearer ${state.currentToken.token}`
           : ''
    }
    
    function saveState(key, state) {
        window.localStorage.setItem(key, JSON.stringify(state))
    }
    

    那么,在我的变异中,我有一些东西可以称之为:

    export const mutations = {
        SET_TOKEN(state, newToken) {
            state.currentToken = newToken
            saveState('currentToken', newToken)
            setDefaultAuthHeaders(state)
        },
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-13
      • 2018-05-12
      • 2020-01-17
      • 2020-06-15
      • 2018-06-16
      • 2020-01-29
      • 2020-05-22
      • 2020-10-05
      相关资源
      最近更新 更多