Ajmal-Hossain
Ajmal-Hossain

Reputation: 215

Router Navigation is not working properly in vue.js

I am trying to protect my routers in vue.js. I made it for user authentication that if a user is not logged in then he/she will not be able to access router. It's fine but after logging in as a patient if the patient try to access the router for doctor, it goes to the doctor profile. that means my solution is only working to see whether the user is logged in or not, it does not check whether the is authenticated to access the router of any other kind of user. please, anyone give a solution

Here is what I tried

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth) {
    const authUser = JSON.parse(window.localStorage.getItem('authUser'));
    if (authUser && authUser.access_token) {
      next();
    } else {
      next({ name: 'login' });
    }
  }
  next();
});

shared code `

  beforeEnter: (to, from, next) => {
        if (authUser.role === '1') {
          next();
        }
        else {
            alert("access denied!")
            next({ path: '/${roleshash[authUser.role]}' })
        }
    }

`

Upvotes: 1

Views: 906

Answers (1)

chans
chans

Reputation: 5260

As per the below implementation, it checks only for authentication of the current user, but not authorization. You need to have role as property in autheUser object

you can defile all the available roles in an array:

const Roles = ['doctor', 'patient']; const authUser = { acces_token: 'xxx', role: 'patient' };

always empty object {} is truthy, so I have added

!!Object.keys(authUser).length

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth) {
    const authUser = JSON.parse(window.localStorage.getItem('authUser'));
    if (!!Object.keys(authUser).length && authUser.access_token && Roles.includes(authUser.role)) {
      next();
    } else {
      next({ name: 'login' });
    }
  }
});

Also You need to use pre route gaurds or incomponent guard to have strong authorization to restrict the user

pre-router guard

const router = new VueRouter({
  routes: [
    {
      path: '/patient',
      component: Patient,
      beforeEnter: (to, from, next) => {
        if (authUser.role === 'patient' || authUser.role === 'doctor') {
          next();
        } else {  //access denied }
      }
    }
  ]
})

In-component guard

const patientComponent = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    if (authUser.role === 'patient' || authUser.role === 'doctor') {
      // enter
    } else { this.$router.push('/accessDenied') }
  }
}

const doctorComponent = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    if (authUser.role === 'doctor') {
      // enter
    } else { this.$router.push('/accessDenied') }
  }
}

Updated fix:

const rolehash = {
1: 'admin',
2: 'doctor',
3: 'patient',
4: 'administrator'
}

Your question is if the user is patient and trying to hit url localhost:8080://doctor, it should redirect to patient and should not enter

lets say here auth.role is 3

routes: [
    {
      path: '/doctor',
      component: Doctor,
      beforeEnter: (to, from, next) => {
        if (authUser.role  === 2) {         
           next();
        }
        else {
            next({ path: `/${roleshash[authUser.role]}` })
        }
    }
    }
  ]

also you can try this approach as well inside Doctor component

import store from 'store';

beforeRouteEnter (to, from, next) {
    if (store.authUser.role  === 2) {         
           next();
        }
        else {
           next({ path: `/${roleshash[authUser.role]}` })
        }
  },

Upvotes: 1

Related Questions