我有一个只能由经过身份验证的用户访问的 /profile
路由。根据研究,推荐的方法是使用 vue-router
的导航守卫:
这是路由对象:
{
path: '/profile',
name: 'MyProfile',
component: () => import('@/views/Profile.vue'),
meta: { requiresAuth: true }
},
这是路由器的导航守卫:
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (isAuthenticated()) {
next()
}
else {
alert('Auth required!')
next('/login')
}
}
})
上面的 isAuthenticated()
函数将一个 jwt token (存储在 cookie 中)发送到 /jwt/validate
端点,该端点验证 token 并返回一个 200好的
响应:
export function isAuthenticated() {
axios.post(`${baseUrl}/token/validate`, {}, { withCredentials: true })
.then(resp => resp.statusText == 'OK')
.catch(err => false)
}
使用这种方法,每次我们访问 /profile
路由时,我们都会向 /token/validate
端点发出 POST 请求。这很有效。 但是,每次都提出这个要求是不是太过分了?
我的解决方案
我想知道是否有某种方法可以将数据本地存储在内存中。我想到了两种可能的解决方案:
- 选项 1: 将数据存储在 vuex store 上,但是我了解到 vuex store 对象是 accessible via the browser's console .这意味着任何人都可以修改访问逻辑以访问 protected 路由。
- 选项 2:将其存储在自定义
Vue.prototype.$user
对象中,但这与 accessible via console 类似因此具有与选项 1 相同的安全风险。
本质上,我的问题是:是否可以选择访问 protected 路由而不必每次都在服务器端验证 jwt token ?
最佳答案
您应该在用户最初加载应用程序时向服务器查询 token 是否有效一次。之后,通常没有理由再次检查。如果 session 在服务器上过期,那么您执行的任何其他 API 调用都应返回 401 响应(或您选择返回错误的任何其他方式)并且您的应用程序可以对此采取行动。您的应用程序可以对此采取行动。
如果您的配置文件路由正在从服务器获取数据以显示并且服务器正在为该请求正确验证用户,那么用户是否试图操纵 Vuex 存储或 Vue 状态并不重要,因为他们不会能够加载数据。
在vue router中做认证,其实更多的是为了方便,而不是真正的安全。
不要浪费时间试图阻止恶意用户探索 Vue 应用程序 - 这注定是一场失败的战斗,因为所有代码都已加载到浏览器中。
如果您真的坚持某种保护,您可以使用动态加载的 webpack block 拆分应用程序,并将您的 Web 服务器配置为仅服务于这些 block 以正确验证和授权用户。也就是说,我希望这样的配置很困难且容易出错,我不推荐它。
关于vue.js - Vue-Router:通过正确的身份验证保护私有(private)路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71074351/