Vue.js 手动输入后验证 URL

Vue.js authentication after manually entering URL

在我的 routes 数组 main.js 中,我设置了

meta : { requiresAuth: true }

UserLogin 页面之外的每个组件。

关于导航分辨率,我在每条路线前设置了检查如下:

router.beforeEach((to, from, next) => {
    const currentUser = firebase.auth().currentUser;
    const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
    const currentUserState = !!currentUser;

    console.table({ currentUserState, requiresAuth });

    if (requiresAuth && !currentUser) {
        next('/login');
    } else {
        next();
    }
}

使用此设置,一切几乎都像 expected/intended 一样工作。登录用户可以去任何地方,匿名用户被重定向到 localhost/login.

但是,此检查和重定向仅在用户通过单击网络应用程序中的链接进行导航时起作用(这些链接都是 <router-link> :to="{ name: 'SomeComponent' }"

当任何用户(注册用户或匿名用户)尝试通过键入或复制粘贴网址在应用程序中导航时,应用程序会自动将他们发送到登录页面。

从 console.table 输出中,我可以看到手动输入 url 总是导致 currentUserState 为 false。

它不会保持错误:已登录 (currentUserState === true) 的用户,然后手动导航到某处 (currentUserState === false),他们的 currentUserState 恢复到 true

我只能隐约猜到是渲染的问题,firebase.auth()

firebase.initializeApp(config)

// you need to let firebase try and get the auth state before instantiating the 
// the Vue component, otherwise the router will be created and you haven't 
// resolved whether or not you have a user

firebase.auth().onAuthStateChanged(function(user) {
    app = new Vue({
      el: '#app',
      template: '<App/>',
      components: { App },
      router
    })
});

我找到了解决这个错误的方法。

在我的 Vuex store.js 中,状态快照存储在 localStorage 中。每当存储本身发生变化时都会更新此快照,因此 localStorage 备份始终与 Vue.js 应用程序本身的实际状态保持同步。

store.subscribe((mutation, state) => {
  localStorage.setItem('store', JSON.stringify(state));
});

这个 store.subscribe 在我的 store.js 中设置在导出行之前。

商店中还定义了一个名为initStore的函数,如下

initStore(state) {
  if (localStorage.getItem('store')) {
    this.replaceState(Object.assign(state, JSON.parse(localStorage.getItem('store'))));
  }
},

在我的商店对象之后,它立即被调用 store.commit('initStore').