В настоящее время я использую метод, описанный в Аутентификация в 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()
, но с эстетической точки зрения это мне не подходит.Даже если это сработает, есть ли более идиоматический способ?