Moja aplikacja korzysta z interfejsu API Firebase do uwierzytelniania użytkowników, zapisując stan logowania jako wartość logiczną w stanie Vuex.
Kiedy użytkownik się loguje, ustawiam status logowania i odpowiednio wyświetlam przycisk Zaloguj / Wyloguj.
Jednak po odświeżeniu strony stan aplikacji vue zostaje utracony i zresetowany do wartości domyślnych
Powoduje to problem, ponieważ nawet gdy użytkownik jest zalogowany, a strona jest odświeżana, status logowania jest ustawiany z powrotem na fałsz, a zamiast przycisku wylogowania wyświetlany jest przycisk logowania, mimo że użytkownik pozostaje zalogowany ....
Co mam zrobić, aby temu zapobiec
Czy mam używać plików cookie Czy jest dostępne inne lepsze rozwiązanie ...
-
-
Odpowiedzi:
To znany przypadek użycia. Istnieją różne rozwiązania.
Na przykład można użyć
vuex-persistedstate
. To jest wtyczkavuex
do obsługi i przechowywania stanu między odświeżeniami strony.Przykładowy kod:
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 }) }) ] })
To, co tutaj robimy, jest proste:
js-cookie
getState
próbujemy załadować zapisany stan zCookies
setState
ratujemy nasz stanCookies
Dokumenty i instrukcje instalacji: https://www.npmjs.com/package/vuex-persistedstate
źródło
Tworząc stan VueX, zapisz go w pamięci sesji za pomocą wtyczki vuex-persistedstate . W ten sposób informacje zostaną utracone po zamknięciu przeglądarki. Unikaj używania plików cookie, ponieważ te wartości będą przesyłane między klientem a serwerem.
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: { //.... } });
Użyj,
sessionStorage.clear();
gdy użytkownik wyloguje się ręcznie.źródło
vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
Stan Vuex jest przechowywany w pamięci. Wczytanie strony spowoduje wyczyszczenie obecnego stanu. Dlatego stan nie utrzymuje się przy przeładowaniu.
Ale
vuex-persistedstate
wtyczka rozwiązuje ten problemTeraz zaimportuj to do sklepu.
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()] });
Działało idealnie z pojedynczą linijką kodu:
plugins: [createPersistedState()]
źródło
Myślę, że użycie plików cookie / localStorage do zapisania stanu logowania może spowodować błąd w niektórych sytuacjach.
Firebase już rejestruje dla nas dane logowania w localStorage, w tym expirationTime i refreshToken.
Dlatego użyję haka utworzonego przez Vue i interfejsu API Firebase, aby sprawdzić stan logowania.
Jeśli token wygasł, interfejs API odświeży go za nas.
Dzięki temu możemy upewnić się, że stan logowania w naszej aplikacji jest taki sam, jak w 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.'); } }); }, });
źródło
postaw na stan:
producer: JSON.parse(localStorage.getItem('producer') || "{}")
postaw na mutacje:
localStorage.setItem("producer",JSON.stringify(state.producer)) // OR localStorage.removeItem("producers");
dla mnie działa dobrze!
źródło
Rozwiązałem to, resetując nagłówki za każdym razem, gdy ładuję ponownie, również pobieram dane użytkownika, nie wiem, co jest lepsze ...
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() }) } } } }) })
źródło