Mi aplicación usa la API de Firebase para la autenticación de usuarios, y guarda el estado de inicio de sesión como un valor booleano en un estado de Vuex.
Cuando el usuario inicia sesión, configuro el estado de inicio de sesión y visualizo condicionalmente el botón Iniciar sesión / Cerrar sesión en consecuencia.
Pero cuando se actualiza la página, el estado de la aplicación vue se pierde y se restablece al valor predeterminado
Esto causa un problema, ya que incluso cuando el usuario está conectado y la página se actualiza, el estado de inicio de sesión se establece de nuevo en falso y se muestra el botón de inicio de sesión en lugar del botón de cierre de sesión, aunque el usuario permanece conectado ...
¿Qué debo hacer para prevenir este comportamiento?
¿Debo usar cookies o hay otra solución mejor disponible?
-
-
Respuestas:
Este es un caso de uso conocido. Existen diferentes soluciones.
Por ejemplo, se puede usar
vuex-persistedstate
. Este es un complemento paravuex
manejar y almacenar el estado entre actualizaciones de página.Código de muestra:
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 }) }) ] })
Lo que hacemos aquí es simple:
js-cookie
getState
intentamos cargar el estado guardado deCookies
setState
salvamos nuestro estado paraCookies
Documentos e instrucciones de instalación: https://www.npmjs.com/package/vuex-persistedstate
fuente
Al crear su estado de VueX, guárdelo en el almacenamiento de la sesión con el complemento vuex-persistedstate . De esta forma, la información se perderá cuando se cierre el navegador. Evite el uso de cookies ya que estos valores viajarán entre el cliente y el servidor.
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: { //.... } });
Úselo
sessionStorage.clear();
cuando el usuario cierre la sesión manualmente.fuente
vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
El estado de Vuex se guarda en la memoria. La carga de la página purgará este estado actual. Es por eso que el estado no persiste en la recarga.
Pero el
vuex-persistedstate
complemento resuelve este problemaAhora importe esto a la tienda.
import Vue from 'vue' import Vuex from 'vuex' import account from './modules/account' import createPersistedState from "vuex-persistedstate"; Vue.use(Vuex); const store = new Vuex.Store({ modules: { account, }, plugins: [createPersistedState()] });
Funcionó perfectamente con una sola línea de código:
plugins: [createPersistedState()]
fuente
Creo que usar cookies / localStorage para guardar el estado de inicio de sesión podría causar algún error en alguna situación.
Firebase ya registra la información de inicio de sesión en localStorage para nosotros, incluidos expirationTime y refreshToken.
Por lo tanto, usaré el gancho creado por Vue y la API de Firebase para verificar el estado de inicio de sesión.
Si el token expiró, la API actualizará el token por nosotros.
Entonces, podemos asegurarnos de que la visualización del estado de inicio de sesión en nuestra aplicación sea igual a 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.'); } }); }, });
fuente
poner en estado:
producer: JSON.parse(localStorage.getItem('producer') || "{}")
poner mutaciones:
localStorage.setItem("producer",JSON.stringify(state.producer)) // OR localStorage.removeItem("producers");
funciona bien para mi!
fuente
Resolví esto restableciendo mis encabezados cada vez que recargo, también obtengo datos de usuario, no sé qué es mejor ...
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() }) } } } }) })
fuente