Reputation: 1687
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
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