mafortis
mafortis

Reputation: 7128

Vue router can't validate user

Some of my app routes are restricted for admins only for that I've added requiresAdmin: true, to those routes meta but somehow I doesn't prevent other users of accessing those routes.

Code

PS: I've commented parts for better understanding.

const router = new VueRouter({
    mode: "history",
    routes: [
        // ADMIN ROUTES
        {
            path: '/export',
            name: 'ExportXML',
            component: ExportXML,
            meta: {
                requiresAuth: true,
                requiresAdmin: true,  // only admins can see this page
                layout: 'admin',
                name: 'Export XML',
            }
        },
    ]
});

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (!store.getters.isLoggedIn) {
            next({
                name: 'login'
            })
        } else {
            next()
        }
    }
    if (to.matched.some(record => record.meta.requiresAdmin)) {
        // first make sure getter can get logged user data
        if (store.getters.loggedUser && !store.getters.loggedUser === undefined) {
            // then check if loged user "type" is admin (any other possebilities are denied)
            if (!store.getters.loggedUser.type === 'admin' || store.getters.loggedUser.type === '' || store.getters.loggedUser.type === null || store.getters.loggedUser.type === undefined || store.getters.loggedUser.type === 'worker') {
                next({
                    name: 'dashboard'
                })
            } else {
                next()
            }
        }
    }
    else {
        next()
    }
});


router.afterEach((to, from) => {
    Vue.nextTick(() => {
        document.title = to.pageTitle || 'Testing Site';
    });
});

export default router;

Any idea why for example my user with type of worker still can see exports page while is restricted for admins only?

Upvotes: 0

Views: 217

Answers (2)

Phil
Phil

Reputation: 164767

The issue is here

if (to.matched.some(record => record.meta.requiresAuth)) {
  if (!store.getters.isLoggedIn) {
    next({
      name: 'login'
    })
  } else {
    next() // 👈 specifically here
  }
}

This skips any more checks once you've validated that the user is logged in.

You need to move the next if block checking for admins into that else block above, replacing the next(). In fact, you could clean this up by using return to exit the processing when required

if (to.matched.some(({ meta }) => meta.requiresAuth) && !store.getters.isLoggedIn) {
  return next({ name: 'login' }) // not logged in, redirect to login
}
if (to.matched.some(({ meta }) => meta.requiresAdmin)
    && store.getters.loggedUser.type !== 'admin') {
  return next({ name: 'dashboard' }) // not admin, redirect to dashboard
}
next() // otherwise, everything is fine

Edit modest-meninsky-w3u2z

Upvotes: 1

sazzad
sazzad

Reputation: 525

check my comment in the code

if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!store.getters.isLoggedIn) { // <== problem in condition
        next({
            name: 'login'
        })
    } else {
        next().  //  this line is always executed if a user is logged in. so any any logged in user can visit url in your application
    }
}

one possible solution may be

if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!store.getters.isLoggedIn) { 
        next({
            name: 'login'
        })
    } else {
        
        // then check if loged user "type" is admin (any other possebilities are denied)
        if (!store.getters.loggedUser.type === 'admin' || store.getters.loggedUser.type === '' || store.getters.loggedUser.type === null || store.getters.loggedUser.type === undefined || store.getters.loggedUser.type === 'worker') {
            next({
                name: 'dashboard'
            })
        } else {
            next()
        }
    }
    
}
else {
  next()
}

Upvotes: 0

Related Questions