Search code examples
vue.jsvuejs2axiosvuexnuxt.js

Config Axios globally with Authenticated in NuxtJS - VueJS


I finding way to config Axios globally with Authenticated in NuxtJS - VueJS (I use mainly NUXTJS).

All I need is: If user logged in and have token in $store, axios will get this token. If user is anonymous, axios wont get this token

~/plugins/axios

import axios from 'axios'
import AuthenticationStore from '~/store'

var api = axios.create({
  baseURL: 'http://localhost:8000/api/v1/',
  'headers': {'Authorization': 'JWT ' + AuthenticationStore.state.token}
})

api.interceptors.request.use(function (config) {
  config.headers = {
    'Authorization': AuthenticationStore.state.token ? 'JWT ' + AuthenticationStore.state.token : ''
  }
  return config
}, function (error) {
  // Do something with request error
  return Promise.reject(error)
})

export default api

~/store/index.js

const AuthenticationStore = () => {
  return new Vuex.Store({
    state: {
      token: null
    },
    mutations: {
      SET_TOKEN: function (state, token) {
        state.token = token
        instance.defaults.headers = { Authorization: 'Bearer ' + token }
      }
    },
    actions: {
      ....
    }
  })
}

export default AuthenticationStore

Error: [nuxt] Error while initializing app TypeError: Cannot read property 'token' of undefined


Solution

  • I would suggest to use interceptor instead which is more flexible and getting token when making request not on creation. Try something like that to avoid issues with not set token.

    // ~/plugins/axios
    import axios from 'axios'
    import AuthenticationStore from '~/store'
    
    var api = axios.create({
      baseURL: 'http://localhost:8000/api/v1/',
      'headers': {'Authorization': 'JWT ' + AuthenticationStore.state.token}
    })
     api.interceptors.request.use(function (config) {
      config.headers = {
        'Authorization': AuthenticationStore.state.token ? 'Bearer ' + AuthenticationStore.state.token : ''
      }
      return config
    }, function (error) {
      // Do something with request error
      return Promise.reject(error)
    })
    export default api
    

    If you need to have no auth header, you need to add if at the begging of the interceptor.

    Issue with your store: You are exporting function when you should export instance of store, so this is wrong:

    const AuthenticationStore = () => { 
    

    You should export instance so:

    const AuthenticationStore = new Vuex.Store({ ...
    

    Please visit https://vuex.vuejs.org/guide/ to get better understanding. It is not bad that you don't understand it fully! Modules/instances/exporting in JS is not really easy to understand fully. Just try to learn it more. Good luck.