Vue-Router:通过正确的身份验证保护私有路由

Vue-Router: Protecting private routes with authentication the right way

我有一个 /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 令牌(存储在 cookie 中)发送到 /jwt/validate 端点,该端点验证令牌和 returns 一个 200 OK 响应:

export function isAuthenticated() {
  axios.post(`${baseUrl}/token/validate`, {}, { withCredentials: true })
    .then(resp => resp.statusText == 'OK')
    .catch(err => false)
}

使用这种方法,每次访问 /profile 路由时,我们都会向 /token/validate 端点发出 POST 请求。这很有效。 但是,每次都提出这个要求是不是太过分了?

我的解决方案

我想知道是否有某种方法可以将数据本地存储在内存中。我想到了两种可能的解决方案:

  1. 选项 1: 将数据存储在 vuex store 上,但是我了解到 vuex store 对象是 。这意味着任何人都可以修改访问逻辑以访问受保护的路由。
  2. 选项 2: 将其存储在自定义 Vue.prototype.$user 对象中,但这与 accessible via console 类似,因此具有与选项 1 相同的安全风险。

基本上,我的问题是:是否有一个选项可以访问受保护的路由,而不必每次都在服务器端验证 jwt 令牌?

您应该在用户最初加载应用程序时查询服务器一次令牌是否有效。之后,通常没有理由再次检查。如果会话在服务器上过期,那么您执行的任何其他 API 调用都应该 return 401 响应(或您选择 return 错误的任何其他方式)并且您的应用程序可以采取行动that.and 您的应用程序可以对此采取行动。

如果您的个人资料路由正在从服务器获取数据以显示并且服务器正在针对该请求正确验证用户,那么用户是否试图操纵 Vuex 存储或 Vue 状态并不重要,因为他们赢了'能够加载数据。

在vue router中做认证,其实是为了方便,而不是为了安全。

不要浪费时间试图阻止恶意用户探索 Vue 应用程序 - 这注定是一场失败的战斗,因为所有代码都已加载到浏览器中。


如果您真的坚持某种保护,您可以使用动态加载的 webpack 块拆分应用程序,并将您的 Web 服务器配置为仅服务于这些块以正确验证和授权用户。也就是说,我希望这样的配置很困难且容易出错,我不推荐它。