1

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]}' })
        }
    }

`

1
  • it is a bit unclear from the question, but you appear to be dealing with roles or permissions? You would need to check those permissions somehow, probably with an API request from which you would then call next() asynchronously. Perhaps you could also try JSON web tokens that contain these permissions, but thats a different story. Commented Oct 16, 2019 at 15:54

1 Answer 1

1

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]}` })
        }
  },
Sign up to request clarification or add additional context in comments.

4 Comments

Comments are not for extended discussion; this conversation has been moved to chat.
Dude a problem arose. Above solution is working when a user is logged in. But if a user want to log in it generate an error, Cannot read property 'role' of null . ` beforeEnter: (to, from, next) => { if (authUser.role === '4') { next(); } else { Swal.fire({ type: 'error', title: 'Access Denied!', text: 'Unauthorized access occured' }) next({ path: '/' + roleshash[authUser.role] }) } } ` here is the problem.
because in case of log in it must not check the role. It will place the role for the user. Let say I am patient and I want to log in. Now I don't need to check the beforeEnter guard because I am authenticated by server. I must log in and set the role for me as 4. beforeEnter should work only if a logged in user want to access unauthorized router
There are different design patterns can be used in authorization, do you have rank for the roles

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.