Saadettin Yasir AKEL
Saadettin Yasir AKEL

Reputation: 81

Vuex Axios Token Undefined

I am trying to perform user login with Vuejs and Django. I use vuex and django restframework as a component. When I use the user login form with Vuex store, django creates token for the user. However, vue js does not detect the generated user token. token is returning as undefined.

My store.js codes

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
}
...

Login page

...
  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))
    }
  }
...

Upvotes: 0

Views: 1359

Answers (2)

tonhozi
tonhozi

Reputation: 450

If anyone else runs into it:

I have it calling some private helpers:

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))
}

Then, in my mutation I have something to call it:

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

Upvotes: 0

Sang Dang
Sang Dang

Reputation: 489

Your main.js runs before store.js. The token only be generated after you call login action in store.js. After that nothing trigger the localStorage.getItem() method again, so the token remains undefined there.

The easiest way to get token is put another entry in getters for token, then use mapGetters to get it from any component you want.

Upvotes: 1

Related Questions