可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
My app uses the Firebase API for User Authentication, saving the Login status as a boolean value in a Vuex State.
When the user logs in I set the login status and conditionally display the Login/Logout button accordingly.
But when the page is refreshed, the state of the vue app is lost and reset to default
This causes a problem as even when the user is logged in and the page is refreshed the login status is set back to false and the login button is displayed instead of logout button even though the user stays logged in....
What shall I do to prevent this behavior
Shall i use cookies
Or any other better solution is available...
回答1:
This is a known use case. There are different solutions.
For example, one can use vuex-persistedstate
. This is a plugin for vuex
to handle and store state between page refreshes.
Sample code:
import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
const store = new Store({
// ...
plugins: [
createPersistedState({
getState: (key) => Cookies.getJSON(key),
setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
})
]
})
What we do here is simple:
- you need to install
js-cookie
- on
getState
we try to load saved state from Cookies
- on
setState
we save our state to Cookies
Docs and installation instructions: https://www.npmjs.com/package/vuex-persistedstate
回答2:
I think use cookies/localStorage to save login status might cause some error in some situation.
Firebase already record login information at localStorage for us include expirationTime and refreshToken.
Therefore I will use Vue created hook and Firebase api to check login status.
If token was expired, the api will refresh token for us.
So we can make sure the login status display in our app is equal to Firebase.
new Vue({
el: '#app',
created() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
log('User is logined');
// update data or vuex state
} else {
log('User is not logged in.');
}
});
},
});
回答3:
put on state:
producer: JSON.parse(localStorage.getItem('producer') || "{}")
put on mutations:
localStorage.setItem("producer",JSON.stringify(state.producer)) // OR
localStorage.removeItem("producers");
works fine for me!
回答4:
I've solved this by resetting my headers every time I re-load also fetch user data, I don't know what is better ...
new Vue({
el: 'vue',
render: h => h(VueBox),
router,
store,
computed: {
tokenJWT () {
return this.$store.getters.tokenCheck
},
},
created() {
this.setAuth()
},
methods:
Object.assign({}, mapActions(['setUser']), {
setAuth(){
if (this.tokenJWT) {
if (this.tokenJWT === 'expired') {
this.$store.dispatch('destroyAuth')
this.$store.dispatch('openModal')
this.$store.dispatch('setElModal', 'form-login')
} else {
window.axios.defaults.headers.common = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.tokenJWT
}
axios.get( api.domain + api.authApi )
.then(res => {
if (res.status == 200) {
this.setUser( res.data.user )
}
})
.catch( errors => {
console.log(errors)
this.destroyAuth()
})
}
}
}
})
})
回答5:
When creating your VueX state, save it to session state. In this way, the information will be lost when the browser is closed. Avoid use of cookies as these values will travel between client and server.
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from "vuex-persistedstate";
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [createPersistedState({
storage: window.sessionStorage,
})],
state: {
//....
}
});
Use sessionStorage.clear();
when user logs out manually.