margherita pizza
margherita pizza

Reputation: 7145

VueJS router guards to implement access control mechanism

My use case is something like this.

  1. I have main routes and nested routes in my system.
  2. Main routes should be loaded in <router-view></router-view> tags inside the App.vue file and these main routes should not be loaded in any other <router-view></router-view> tags in other vue components.
  3. Sub routes should be loaded in there relevant componet's <router-view></router-view> tags only. Not be loaded in other component's <router-view></router-view> tags.

My problem is now anyone can type the route name in url and navigate to through the entire system with out any barriers even anyone can simply bypass the login through this and login to the system.

I know this can by done using beforeeach route guard. But I have no idea where to put this beforeeach functions and how to connect them all. Can some one give me an idea how to achieve my requirement.

This is my complete routes.js file

//9 root routes

import findYourAccount from './components/find-your-account.vue';
import restPassword from './components/reset-password.vue';
import student from './components/student.vue';
import welcome from './components/welcome.vue';
import admin from './components/admin.vue';
import dataEntry from './components/data-entry.vue';

import resetYourPassword from './components/forgot-password/resetYourPassword.vue';
import emailHasBeenSent from './components/forgot-password/email-has-been-sent.vue';
import noSearchResults from './components/forgot-password/no-search-results.vue';

//student subroutes 7

import buyPapers from './components/student/buyPapers.vue';
import studentDashboard from './components/student/studentDashboard.vue';
import myPapers from './components/student/myPapers.vue';

import startExam from './components/student/startExam.vue';
import QuestionPaper from './components/student/QuestionPaper.vue';
import FinishTheExam from './components/student/viewResults.vue';
import viewTutorProfile from './components/student/viewTutorProfile.vue';

//Admin subroutes 2

import createDataEntryOperators from './components/administrater/createDataEntryOperators.vue';
import adminDashboard from './components/administrater/adminDashboard.vue';

//Data entry subroutes 2

import questionPaperMetaData from './components/data-entry/question-paper-meta-data.vue';
import createExam from './components/data-entry/create-exam.vue';
import createTutorProfile from './components/data-entry/tutor-profile-creation.vue';

export const routes = [
{path:'/findYourAccount',component:findYourAccount},
{path:'/',component:welcome},
{path:'/restPassword',component:restPassword},
{path:'/resetYourPassword',component:resetYourPassword},
{path:'/emailHasBeenSent',component:emailHasBeenSent},
{path:'/noSearchResults',component:noSearchResults},

{path:'/student',component:student, children:[
  {path:'/buyPapers',component:buyPapers},
  {path:'/studentDashboard',component:studentDashboard},
  {path:'/myPapers',component:myPapers},

  {path:'/startExam',component:startExam,name:'startExam'},
  {path:'/QuestionPaper',component:QuestionPaper},
  {path:'/FinishTheExam',component:FinishTheExam},
  {path:'/viewTutorProfile',component:viewTutorProfile, name:'tutorProfile'}
]},
{path:'/admin',component:admin,children:[
  {path:'/createDataEntryOperators',component:createDataEntryOperators},
  {path:'/adminDashboard',component:adminDashboard}
]},
{path:'/dataEntry',component:dataEntry,children:[
  {path:'/createExam',component:createExam},
  {path:'/createTutorProfile',component:createTutorProfile},
  {path:'/questionPaperMetaData',component:questionPaperMetaData}
]}
]
//export default routes

This is my App.vue file where only main routes should be loaded.

<template>
  <div class="fluid-container">
    <app-header></app-header>
    <div style="min-height:610px;">
      
      <router-view></router-view>

    </div>

<div>
  <app-footer></app-footer>
</div>

  </div>
</template>

This is one of my main route (student) which has nested routes.

<template lang="html">
  <div class="">
    <div class="row">
      <div class="col-md-3">

        <ul class="nav flex-column">
          <li class="nav-item">
            <router-link to="/studentDashboard">Dashboard</router-link>
          </li>

          <li class="nav-item">
            <router-link to="/buyPapers">Buy papers</router-link>
          </li>

          <li class="nav-item">
            <router-link to="/myPapers">My papers</router-link>
          </li>

  </ul>
      </div>
      <div class="col-md-9">
        <router-view></router-view>
      </div>

    </div>

  </div>
</template>

Upvotes: 2

Views: 2457

Answers (1)

David Yunevich
David Yunevich

Reputation: 194

BeforeEach guard should be used in the same place where you initialize VueRouter. Check out docs: https://router.vuejs.org/en/advanced/navigation-guards.html

To provide protection of routes you need to check user type or permissions in BeforeEach guard. To store user permissions overall app, you probably need to use Vuex:

import store from '../store'
router.beforeEach((to, from, next) => {
 if (to.path === '/admin') {
    if (store.state.user.type === 'student') next('/student')
    next()
 }
})

Upvotes: 2

Related Questions