Farsen
Farsen

Reputation: 1687

Wait for state update in vuejs router´s beforeEnter

I want to restrict access to certain pages in my vue router. Instead of having the auth logic in each component, I would prefer, for instance, to just have a 'hasUserAccess' check in my child-routes where it´s needed

{
    path: 'admin',
    name: 'admin',
    beforeEnter: hasUserAccess,
    component: () => import(/* webpackChunkName: "admin" */ '@/_ui/admin/Admin.vue')
},

...

function hasUserAccess(to, from, next) {
    if (myState.user.isAdmin) {
        next();
    } else {
        next({ path: '/noaccess' });
    }
}

This works as intended when navigating from another page to the 'admin' page. This does not work when i manually type the /admin url (or pressing f5 while on the admin page) because the user object hasn´t been fetched from the server yet (some other logic is taking care of fetching the user). The 'beforeEnter' is async, but as far as I know it ain´t possible to 'watch' the user object, or await it, from the router since the router is not a typical vue component.

So how is this common problem normally solved?

Upvotes: 2

Views: 1803

Answers (1)

ZeroLiam
ZeroLiam

Reputation: 222

Just apply the beforeEach to the router itself. On the router file, you could do this:

router.beforeEach((to, from, next) => {
  //in case you need to add more public pages like blog, about, etc
  const publicPages = ["/login"]; 
  //check if the "to" path is a public page or not
  const authRequired = !publicPages.includes(to.path); 

  //If the page is auth protected and hasUserAccess is false
  if (authRequired && !hasUserAccess) {
    //return the user to the login to force the user to login
    return next("/login"); 
  }
  //The conditional is false, then send the user to the right place
  return next();
});

Try to modify this at your convenience, but this is more or less what I do in a situation like yours.

Upvotes: 0

Related Questions