Как мне прочитать и проанализировать куки и сохранить результаты в Vuex до запуска охраны Vue-Router - PullRequest
0 голосов
/ 19 мая 2019

В настоящее время я использую метод, описанный в Аутентификация в SPA Правильным способом , где заголовок и полезная нагрузка JWT хранятся в файле cookie сеанса.Я хочу прочитать этот файл cookie, если он доступен, как только загрузится мой SPA, даже если пользователь перейдет по глубокой ссылке, и создать объект User, чтобы проверить его или ее разрешения для запрошенного компонента.

В настоящее время я читаю cookie, инициализирую User и сохраняю его в своем хранилище Vuex в событии App.vue created().Здесь я рассуждаю, чтобы обеспечить создание User всегда, независимо от того, насколько глубоко пользователь изначально заходит на сайт, без дублирования кода.

Я попытался разместить логику, сравнивая разрешения User стребования к компонентам в событиях Vue-Router beforeEnter() и beforeRouteEnter(), но, похоже, они срабатывают до created() приложения App.vue (даже если компоненты являются дочерними для 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)
    }
  },
}
[...]

routs / 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>

Я ожидаю, что loginFromCookie() будет вызвано из события App.vue 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()

Кажется, что перемещение логики для обработки любых файлов cookie и создания экземпляра User может работать в событии Vue-Router beforeEach(), но с эстетической точки зрения это мне не подходит.Даже если это сработает, есть ли более идиоматический способ?

...