Обновите токен Vuex перед входом в маршрутизацию

У меня есть интерфейсы внешнего веб-приложения с API, встроенным в Laravel с Passport.

Моя проблема в том, что когда я обновляю свою страницу (в SPA, написанном с помощью Vuejs / Vuex), я должен обновить свой токен для сеанса обновления с моим Api.

Я пробовал использовать main.js, но проблема в том, что запрос асинхронный, а ответ пришел после маршрутизации.

main.js

if (localStorage.getItem('refresh_token')) {
   store.dispatch('refresh_token').then(function(response){
      console.log(response);
   });
}
new Vue({
  router,
  store,
  env,
  render: h => h(App)
}).$mount('#app')

Токен обновления функции, вызовите мой Api и с ответом установите новый токен и новый токен обновления. Но моя проблема в том, что я делаю этот вызов таким образом, что могу сделать первый асинхронный вызов на моей «приборной панели» со старым токеном, а затем с новым. Я пробовал по-разному, но не знаю, есть ли лучшая практика.

Итак, мой вопрос: где мне следует обновить токен в приложении Vuejs с помощью хранилища vuex?


person LorenzoBerti    schedule 13.02.2019    source источник


Ответы (2)


Я предлагаю поместить это в свойство mounted вашего компонента Vue верхнего уровня. Если у вас есть другие компоненты, которые зависят от обновления вашего токена, вы можете связать это с переменной состояния в вашем магазине, которая сигнализирует о завершении обновления. Например, с компонентом верхнего уровня App.vue:

...

mounted () {
  store.dispatch('refresh_token')
}

...

Добавление переменной состояния в ваш магазин vueex:

const store = new Vuex.Store({
  state: {
    sessionRefreshed: false
  },
  ..

  mutations: {
    [REFRESH_TOKEN] (state) {
      // existing mutations, and..
      state.sessionRefreshed = true
    },
  },
  ..
  actions: {
    refreshToken ({ commit }) {
      myAsyncFetchToken().then(() => commit(REFRESH_TOKEN))
    },
  }

Это гарантирует, что все ваше приложение знает о состоянии вашего обновления, не заставляя его быть синхронным. Затем, если у вас есть компоненты, требующие обновления токена, вы можете показать загрузочные виджеты, заполнители и т. Д. И использовать наблюдатель для выполнения действий при изменении состояния.

person jpriebe    schedule 14.02.2019
comment
но если я сделаю этот вызов асинхронным, да, я могу показать загрузку, но если бы у меня был другой асинхронный вызов, я рискую совершить вызов со старым токеном, и поэтому я получу 401, не так ли? - person LorenzoBerti; 15.02.2019
comment
Вы не можете контролировать порядок выполнения асинхронных вызовов по самому их определению. Вам решать, как правильно структурировать свое приложение, чтобы вызовы не выполнялись 401, т.е. с использованием переменной состояния и наблюдателей. - person jpriebe; 15.02.2019

Как насчет использования router#beforeEach guard? Я использую его, чтобы выяснить, хранится ли токен аутентификации в файле cookie, прежде чем обращаться к любому «ограниченному» компоненту. Если токен не установлен, я перенаправляю на /login.

Я понимаю, что мой сценарий - это именно то, о чем вы просите, но я надеюсь, что вы сможете использовать его для расширения своей реализации.

person Simon    schedule 14.02.2019
comment
интересно, я попробую, я звоню в beforeEach для нового свежего токена, если срок действия токена истек, и жду ответа на вызов next (), верно? - person LorenzoBerti; 15.02.2019
comment
Да, звучит разумно. - person Simon; 15.02.2019