我目前正在使用Authentication in SPA the Right Way中所述的方法,其中JWT标头和有效负载存储在会话cookie内。我希望在SPA加载后立即读取此cookie(如果有),即使用户遵循深层链接,也要构造一个User
对象以检查他或她对所请求组件的权限。
当前,我正在读取cookie,初始化User
并将其持久保存到App.vue的created()
事件中的Vuex存储中。我的目的是确保无论用户最初访问该网站的深度如何,都始终创建User
,而无需复制代码。
我尝试在Vue-Router的User
和beforeEnter()
事件中放置将beforeRouteEnter()
的权限与组件要求进行比较的逻辑,但是这些似乎在App.vue的事件之前触发直接访问深层链接时,created()
(即使这些组件是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>
[...]
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)
}
},
}
[...]
[...]
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
},
[...]
]
})
<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()
,但是从美学上来说,这对我来说并不正确。即使这行得通,还有其他惯用的方法吗?