在运行Vue-Router Guard之前,如何读取和解析Cookie并将结果存储在Vuex中

时间:2019-05-19 05:42:28

标签: vue.js vuex vue-router

我目前正在使用Authentication in SPA the Right Way中所述的方法,其中JWT标头和有效负载存储在会话cookie内。我希望在SPA加载后立即读取此cookie(如果有),即使用户遵循深层链接,也要构造一个User对象以检查他或她对所请求组件的权限。

当前,我正在读取cookie,初始化User并将其持久保存到App.vue的created()事件中的Vuex存储中。我的目的是确保无论用户最初访问该网站的深度如何,都始终创建User,而无需复制代码。

我尝试在Vue-Router的UserbeforeEnter()事件中放置将beforeRouteEnter()的权限与组件要求进行比较的逻辑,但是这些似乎在App.vue的事件之前触发直接访问深层链接时,created()(即使这些组件是App.vue的子组件)。

App.vue

<script>
  import { mapState, mapActions } from 'vuex'

  export default {
    name: 'app',
    computed: {
      ...mapState({
        user: state => state.auth.user
      })
    },
    methods: {
      ...mapActions('auth', [
        'loginFromCookie',
        'logout'
      ])
    },
    created () {
      this.loginFromCookie()
    }
  }
</script>

store / modules / auth.js

[...]
const actions = {
  loginFromCookie ({ commit }) {
    if (window.$cookies.isKey('jwt_payload')) {
      console.log('loginFromCookie()')
      const jwtDecode = require('jwt-decode')
      const jwtPayload = window.$cookies.get('jwt_payload')
      const decoded = jwtDecode(jwtPayload)
      const user = decoded.sub
      user.isAnon = false
      commit('setUser', user)
    }
  },
}
[...]

routes / index.js

[...]
function guardAgainstNotAnon(to, from, next) {
  console.log('\tguardAgainstNotAnon():')
  console.log('\t\tFails because loginFromCookie() has not been called and User is anon.')
  if (store.state.auth.user.isAnon) {
    next()
  } else {
    next({name: 'home'})
  }
}

export default new Router({
  [...]
  routes: [
    [...]
    {
      path: '/login',
      name: 'login',
      beforeEnter: (to, from, next) => {
        console.log('beforeEnter():')
        guardAgainstNotAnon(to, from, next)
      },
      component: LogIn
    },
    [...]
  ]
})

views / LogIn.vue

<script>
  import guardAgainstAnon from '../routes'

  export default {
    name: "LogIn",
    data: function () {
      return {
        form: {}
      }
    },
    methods: {
      loginUser () {
        this.$store.dispatch('auth/login', this.form)
        this.$router.push({name: 'home'})
      }
    },
    beforeRouteEnter (to, from, next) {
      console.log('beforeRouteEnter():')
      try {
        guardAgainstAnon(to, from, next)
      } catch(err) {
        console.log('\t' + err.name)
        console.log('\tloginFromCookie() has not occurred.')
      }
    }
  }
</script>

我期望在评估路由之前,将从App.vue的loginFromCookie())事件中调用created(,但这似乎并非如此...

控制台

[HMR] Waiting for update signal from WDS...
index.js?e26c:36 beforeEnter():
index.js?e26c:14   guardAgainstNotAnon():
index.js?e26c:15     Fails because loginFromCookie() has not been
                     called and User is anon.
LogIn.vue?c40f:42 beforeRouteEnter():
LogIn.vue?c40f:46   TypeError
LogIn.vue?c40f:47     Component does seem to exist at this point.
auth.js?c7d4:31 loginFromCookie()

在Vue-Router的User事件中,似乎可以移动逻辑来处理所有cookie并实例化beforeEach(),但是从美学上来说,这对我来说并不正确。即使这行得通,还有其他惯用的方法吗?

0 个答案:

没有答案