No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Access the store in routes.js to use navigation guards

    Framework
    5
    12
    8925
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      Gonzalo2683 last edited by

      Re: How to apply access control to different routes in quasar?

      1 Reply Last reply Reply Quote 0
      • Hawkeye64
        Hawkeye64 last edited by

        I do it like this:
        Example route (router/routes.js):

              {
                path: 'live-view',
                name: 'live-view',
                component: () => import('pages/LiveView'),
                meta: {
                  requiresAuth: true,
                  permissions: ['liveview']
                }
              },
        

        Then, in routes/index.js:

        Router.beforeEach((to, from, next) => {
          let allowedToEnter = true
          to.matched.some((record) => {
            // check if there is meta data
            let isLoggedIn = store.getters['auth/isLoggedIn']
            if (!isLoggedIn && record.name === 'home') {
              next({
                path: '/sign-in',
                replace: true
              })
              return
            }
        
            if ('meta' in record) {
              // ------------------------------------------------------------
              // check if user needs to be logged in to access this page
              if ('requiresAuth' in record.meta) {
                if (record.meta.requiresAuth) {
                  // console.log('Page requires auth:', to, from)
                  // this route requires auth, check if user is logged in
                  // if not, redirect to login page.
                  if (!isLoggedIn) {
                    // User is not logged in, redirect to signin page
                    allowedToEnter = false
                    next({
                      path: '/sign-in',
                      replace: true,
                      // redirect back to original path when done signing in
                      query: { redirect: to.fullPath }
                    })
                  }
                }
              }
              // ------------------------------------------------------------
              // check if user has correct permissions to access this page
              if (allowedToEnter && 'permissions' in record.meta) {
                let canProceed = false
                let permissions = record.meta.permissions
                // get currently logged in user permissions
                let token = store.getters['auth/token']
                // decipher the token
                let session = JWT.read(token)
                // check if they are not an admin (administrator)
                if (session.claim.permissions.administrator) {
                  canProceed = true
                }
                else {
                  for (let index = 0; index < permissions.length; ++index) {
                    let permission = permissions[index]
                    // console.log('Permission needed:', permission)
                    if (permission === 'administrator') {
                      if (session.claim.permissions.administrator) {
                        canProceed = true
                      }
                    }
                    else if (permission === 'liveview') {
                      if (session.claim.permissions.liveview) {
                        canProceed = true
                      }
                    }
        ...
        
        G 1 Reply Last reply Reply Quote 0
        • G
          genyded last edited by

          If you don’t want the checks in your route index.js file, you could also put them into a quasar plugin file called guards.js or something and get the same result. That keeps your index.js file cleaner. Either should work but the plugin model has the added effect of being able to seperate them if desired and quickly turn things on/off by simply commenting out the plugin name(s) in quasar.conf.js when needed.

          G 1 Reply Last reply Reply Quote 0
          • G
            Gonzalo2683 @Hawkeye64 last edited by Gonzalo2683

            @hawkeye64

            Thanks for the example, a question ?, did not you need to import the store to be able to use it? Because I try to use it directly and I do not have access to it.

            This is the store in which I am testing, it is a function that is being exported, I am maintaining as function it because the idea is to be able to use it with SSR. When I import this store and access to state from here vuex does not work properly.

            import Vue from 'vue';
            import Vuex from 'vuex';
            
            import example from './module-example';
            
            import config from './config/config';
            
            Vue.use(Vuex);
            
            /*
             * If not building with SSR mode, you can
             * directly export the Store instantiation
             */
            
            export default function (/* { ssrContext } */) {
              const Store = new Vuex.Store({
                state: {
                  value: 0,
                },
                getters: {
                  value: state => state.value,
                },
                mutations: {
                  updateValueMut: (state, payload) => {
                    state.value = payload;
                  },
                },
                actions: {
                  updateValueAct({ commit }, payload) {
                    commit('updateValueMut', payload);
                  },
                },
              });
            
              return Store;
            }
            
            1 Reply Last reply Reply Quote 0
            • G
              Gonzalo2683 @genyded last edited by

              @genyded
              Thanks, I just saw the documentation about the plugins, apparently the store is accessible directly from here.

              1 Reply Last reply Reply Quote 0
              • Hawkeye64
                Hawkeye64 last edited by Hawkeye64

                @Gonzalo2683
                My complete index.js in the router folder:

                import Vue from 'vue'
                import VueRouter from 'vue-router'
                
                import routes from './routes'
                import store from '../store'
                
                import JWT from 'jwt-client'
                
                Vue.use(VueRouter)
                
                const Router = new VueRouter({
                  /*
                   * NOTE! Change Vue Router mode from quasar.conf.js -> build -> vueRouterMode
                   *
                   * If you decide to go with "history" mode, please also set "build.publicPath"
                   * to something other than an empty string.
                   * Example: '/' instead of ''
                   */
                
                  // Leave as is and change from quasar.conf.js instead!
                  mode: process.env.VUE_ROUTER_MODE,
                  base: process.env.VUE_ROUTER_BASE,
                  scrollBehavior: () => ({ y: 0 }),
                  routes
                })
                
                Router.beforeEach((to, from, next) => {
                  let allowedToEnter = true
                  to.matched.some((record) => {
                    // check if there is meta data
                    let isLoggedIn = store.getters['auth/isLoggedIn']
                    if (!isLoggedIn && record.name === 'home') {
                      next({
                        path: '/sign-in',
                        replace: true
                      })
                      return
                    }
                
                    if ('meta' in record) {
                      // ------------------------------------------------------------
                      // check if user needs to be logged in to access this page
                      if ('requiresAuth' in record.meta) {
                        if (record.meta.requiresAuth) {
                          // console.log('Page requires auth:', to, from)
                          // this route requires auth, check if user is logged in
                          // if not, redirect to login page.
                          if (!isLoggedIn) {
                            // User is not logged in, redirect to signin page
                            allowedToEnter = false
                            next({
                              path: '/sign-in',
                              replace: true,
                              // redirect back to original path when done signing in
                              query: { redirect: to.fullPath }
                            })
                          }
                        }
                      }
                      // ------------------------------------------------------------
                      // check if user has correct permissions to access this page
                      if (allowedToEnter && 'permissions' in record.meta) {
                        let canProceed = false
                        let permissions = record.meta.permissions
                        // get currently logged in user permissions
                        let token = store.getters['auth/token']
                        // decipher the token
                        let session = JWT.read(token)
                        // check if they are not an admin (administrator)
                        if (session.claim.permissions.administrator) {
                          canProceed = true
                        }
                        else {
                          for (let index = 0; index < permissions.length; ++index) {
                            let permission = permissions[index]
                            // console.log('Permission needed:', permission)
                            if (permission === 'administrator') {
                              if (session.claim.permissions.administrator) {
                                canProceed = true
                              }
                            }
                            else if (permission === 'liveview') {
                              if (session.claim.permissions.liveview) {
                                canProceed = true
                              }
                            }
                            else if (permission === 'archive') {
                              if (session.claim.permissions.archive) {
                                canProceed = true
                              }
                            }
                            else if (permission === 'alarmsArchiveEvents') {
                              if (session.claim.permissions.alarmsArchiveEvents) {
                                canProceed = true
                              }
                            }
                            else if (permission === 'remoteAccess') {
                              if (session.claim.permissions.remoteAccess) {
                                canProceed = true
                              }
                            }
                            else if (permission === 'settings') {
                              if (session.claim.permissions.settings) {
                                canProceed = true
                              }
                            }
                            else {
                              console.error('Unknown permission in Router.beforeEach:', permission)
                            }
                          }
                        }
                
                        if (!canProceed) {
                          allowedToEnter = false
                          // redirect to not-authorized page
                          next({
                            path: '/not-authorized',
                            replace: true
                          })
                        }
                      }
                    }
                  })
                
                  if (allowedToEnter) {
                    // go to the requested page
                    next()
                  }
                })
                
                export default Router
                
                1 Reply Last reply Reply Quote 0
                • Hawkeye64
                  Hawkeye64 last edited by

                  In conjuntion with this, I also wrote middleware on the server side that receives the JWT for each axios call and then validates it in the routes as well.

                  1 Reply Last reply Reply Quote 0
                  • P
                    paul last edited by

                    @Hawkeye64 With which version of quasar are you using this. I have a very strange issue, accessing the store in the router (same spirit as you are doing it) is possible in 0.15.15 but it fails in 0.17.17.
                    An idea?

                    1 Reply Last reply Reply Quote 0
                    • Hawkeye64
                      Hawkeye64 last edited by

                      Quasar CLI........ v0.17.19
                      Quasar Framework.. v0.17.16
                      1 Reply Last reply Reply Quote 0
                      • P
                        paul last edited by

                        @Hawkeye64 solved. see: https://forum.quasar-framework.org/topic/2825/store-is-no-longer-accessible-in-router/4
                        Thanks for the help.

                        1 Reply Last reply Reply Quote 1
                        • S
                          Sonibaba last edited by

                          This post is deleted!
                          1 Reply Last reply Reply Quote 0
                          • S
                            Sonibaba last edited by Sonibaba

                            Resolved create const Router and export , after Route, use beforeEach with you validate. Saludos desde mexico ❤

                            import Vue from 'vue'
                            import VueRouter from 'vue-router'
                            import { isAuth, isAdmin, isUser } from "./auth";
                            import routes from './routes'
                            
                            Vue.use(VueRouter)
                            const Router = new VueRouter({
                              mode: process.env.VUE_ROUTER_MODE,
                              base: process.env.VUE_ROUTER_BASE,
                              scrollBehavior: () => ({ y: 0 }),
                              routes
                            })
                            
                            Router.beforeEach((to,from, next) => {
                              to.matched.some( route =>{
                                if(route.meta.requiresAuth){
                                  if(!isAuth()){
                                    next({ path: '/' })
                                  }
                                }
                            
                                if(route.meta.requiresAdmin){
                                  if(!isAdmin()){
                                    next({path: '/'})
                                  }
                                }
                            
                                if(route.meta.requiresUser){
                                  if(!isUser()){
                                    next({path: '/'})
                                  }
                                }
                                next()
                              })
                            })
                            export default Router
                            
                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post