Best practice for storing auth tokens in VueJS?
Application-wide data, such as authentication and user information, should go into centralized state. You can use Vuex or a simple shared state. Vuex is awesome but it does add complication so you have to count the cost. If you use Vuex, you can use Vuex persisted state to keep it in localStorage. This should be much faster to access than localStorage. In my experience, localStorage is not reliable and can cause problems. State is the way to go.
For example, modifying your current code to send it to Vuex:
methods: {
login () {
axios.post('/api-token-auth/login/', {
username: this.username,
password: this.pwd1
}).then(response => {
that.$store.commit('LOGIN_SUCCESS', response)
}).catch(error => {
console.log("Error login")
console.log(error)
})
this.dialog = false
}
}
Then over in Vuex (like /store/modules/user.js if using modules):
Vue.use(Vuex)
const state = { token: null}
const mutations = {
LOGIN_SUCCESS(state, response) {
state.token = response.token
}
export default {
state,
mutations
}
And call the token either by a Getter or directly:
this.$store.state.user.token
This assumes store is used by Vue. For example, in main.js you would have:
import store from './store/index.js'
new Vue({
el: '#app',
store
})
I have a web app that store token/refresh token inside Vuex and load data from localStorage only when the store is init. It work well until our users report that they keep got 403 error. Found out they was using 2 (or more) browser tabs open. After the refresh token is fetch our new token is saved to state and local storage, but the other tab is not notice of data change, so they use the old token/refresh token to fetch, and fails :'(
It took me several hours of re-produce and debugging, now I will never put token inside Vuex again