我正在使用vue.js和vue-router开发一个SPA,现在我正在使用JWT处理授权/认证。我整理了后端(APIendpoint),这样它将发出一个令牌来响应登录,并在随后的请求中检查所需的头。我现在想实现客户端(vue.js)端。
根据我的理解,基本上我需要做的是要求对除了'/'和'/login'之外的所有路由进行身份验证。如果存在身份验证,那么我将令牌(在成功登录后存储在localStorage中)提交到授权头中。如果它未能在服务器上成功验证,则作为错误响应的结果,用户将被重定向到“/login”。
因此,我有几个问题,我需要做什么来实现这一点:
>
除了向登录endpoint提交标头之外,如何最好地将标头与每个请求一起提交?我知道,使用JQuery(用于AJAX),我可以配置一个全局的“AJAX设置”,这将导致标头随每个请求一起提交,但是如何指定异常呢?单独地将头添加到每个APIendpoint请求是很麻烦的。
同样,我如何设置一个身份验证预检查,它适用于除了提到的2条路由(“/”和“/login”)之外的所有路由?
考虑到我正在使用是否存在明显有效的身份验证(显然是因为它仍然必须在APIendpoint上进行验证)来确定是否显示某些菜单项等,是否可以使其更加细化,并为不同的权限级别显示不同的内容(由令牌有效负载中的'scope'字段确定)?显然,处理JWT令牌的最简单方法就是确定它是否存在,因此不需要在客户端解析内容。但是考虑到JWT确实允许有意义的内容,那么尝试在客户端和服务器上使用这种意义是不是一个坏主意呢?显然,如果令牌本身是加密的,那么这就变得不太实际了,因此我的想法是使用未加密的令牌(并确保在有效载荷中不暴露任何后果)。
您可以做全局头,当用户经过身份验证后,将令牌添加到全局头中,就像这个例子一样,我使用的是Axios。
axios.defaults.headers.common['Authorization'] = "Bearer"+ authtoken.token
为了检查用户的身份验证或管理网站的部分内容,只需添加全局变量,当用户通过身份验证时,将该变量设置为true。或者,使用Vuex会很容易,你想要隐藏或显示给用户的元素只需在元素中添加v-if(使用Vuex的例子)
<div v-if="this.$store.state.authenticated"> Hide Element from Guests </div>
对于路由,在“路由添加元”字段中指示该路径需要身份验证
{
path: '/dashboard',
component: DashboardPage,
name: 'Dashboard',
meta: {requiresAuth: true} // Meta Field , you can name it
}
在您的Vue路由器配置中,添加导航卫士,它检查元字段的存在,如果为true,则检查用户是否经过身份验证
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
if(to.meta.requiresAuth) { // check the meta field
if(store.state.Authenticated) { // check if the user is authenticated
next() // the next method allow the user to continue to the router
}
else {
next('/') // Redirect the user to the main page
}
}
else {
next()
}
})