Home > Software design >  Vue-Router: Protecting private routes with authentication the right way
Vue-Router: Protecting private routes with authentication the right way

Time:02-12

I have a /profile route that should only be accessible by an authenticated user. From research, the recommended approach is to use vue-router's navigation guard:

Here is the route object:

  {
    path: '/profile',
    name: 'MyProfile',
    component: () => import('@/views/Profile.vue'),
    meta: { requiresAuth: true }
  },

And here is the router's navigation guard:

router.beforeEach((to, from, next) => {
  if (to.matched.some((record) => record.meta.requiresAuth)) {
    if (isAuthenticated()) {
      next()
    }
    else {
      alert('Auth required!')
      next('/login')
    }
  }
})

The isAuthenticated() function above sends a jwt token (stored in cookie) to the /jwt/validate endpoint which validates the token and returns a 200 OK response:

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

With this approach, every time we visit the /profile route, we are making a POST request to the /token/validate endpoint. And this works quite well. However, is it too excessive to make this request every time?

My Solutions

I wonder if there is some way to store the data locally in memory. I thought of two possible solutions:

  1. Option 1: Storing the data on vuex store, however I have learned that the vuex store object is accessible via the browser's console. This means that anyone can modify the access logic to gain access to protected routes.
  2. Option 2: Store it inside a custom Vue.prototype.$user object, however this is similarly accessible via console and therefore has the same security risk as option 1.

Essentially, my question is: is there an option to access a protected route without having to validate the jwt token on the server-side every time?

CodePudding user response:

You should query the server for if the token is valid once when the user initially loads the application. After that, there is usually no reason to check again. If the session expires on the server, then any other API calls you do should return a 401 response (or any other way that you choose to return an error) and your application can act on that.and your application can act on that.

If your profile route is getting data from the server to display and the server is properly validating the user for that request, then it doesn't matter if the user tries to manipulate the Vuex store or Vue state because they won't be able to load the data.

Doing authentication in the vue router is really more for convenience than for actual security.

Don't waste time trying to prevent a malicious user from exploring the Vue application - that is guaranteed to be a losing battle since all of the code is loaded into the browser.


If you really insist on some kind of protection, you can split the application using webpack chunks that are loaded dynamically and configure your web server to only serve those chunks to properly authenticated and authorize users. That said, I would expect such configuration to be difficult and error prone, and I don't recommend it.

  • Related