Home > Back-end >  Redirect to login page when user is logout in Vue
Redirect to login page when user is logout in Vue

Time:10-23

I am very beginner in JS and VUE. I make mini CMS in Vue and Laravel. I create this router in Vue:

import Vue from 'vue'
import Router from 'vue-router'

// Containers
const TheContainer = () => import('@/containers/TheContainer')

// Views
const Dashboard = () => import('@/views/Dashboard')
....

Vue.use(Router)

let router = new Router({
  mode: 'hash', // https://router.vuejs.org/api/#mode
  linkActiveClass: 'active',
  scrollBehavior: () => ({ y: 0 }),
  routes: configRoutes()
})


router.beforeEach((to, from, next) => {
  let roles = localStorage.getItem("roles");

  if(roles != null){
    roles = roles.split(',')
  }
  if(to.matched.some(record => record.meta.requiresAdmin)) {
    if(roles != null && roles.indexOf('admin') >= 0 ){
      next()
    }else{
      next({
        path: '/login',
        params: { nextUrl: to.fullPath }
      })
    }
  }else if(to.matched.some(record => record.meta.requiresUser)) {
    if(roles != null && roles.indexOf('user') >= 0 ){
      next()
    }else{
      next({
        path: '/login',
        params: { nextUrl: to.fullPath }
      })
    }
  }else{
    next()
  }
})

export default router

function configRoutes () { 
  return [
    {
      path: '/',
      redirect: '/dashboard',
      name: 'Home',
      component: TheContainer,
      children: [
        {
          path: 'dashboard',
          name: 'Dashboard',
          component: Dashboard
        },
          ]
        },
  ]
}

It's work fine, but I have 2 problems:

  1. When user is not login - then I need redirect to my login page (/login) - not to /dashboard
  2. When user session was expired - then redirect to login page

If user is login - then first page (and main page) is /dashboard

How can I make it?

Please help me.

CodePudding user response:

What do you think of this:

import Vue from 'vue'
import Router from 'vue-router'

// Containers
const TheContainer = () => import('@/containers/TheContainer')

// Views
const Dashboard = () => import('@/views/Dashboard')
// ....

Vue.use(Router)

let router = new Router({
  mode: 'hash', // https://router.vuejs.org/api/#mode
  linkActiveClass: 'active',
  scrollBehavior: () => ({ y: 0 }),
  routes: configRoutes()
})

// routing logic for not-logged-in
// users with a role
const useToLoginObj = (to) => ({
  path: '/login',
  params: {
    nextUrl: to.fullPath
  }
})

// DON'T DO THIS IN PRODUCTION!
// secure/security info should
// **NEVER** BE SAVED TO LOCALSTORAGE!!!!!
const fetchUserRoles = () => {
  const roles = localStorage.getItem("roles")?.split(',')
  return roles
}

// possible roles as keys
// corresponding required meta as value
const rolesDict = {
  admin: 'requiresAdmin',
  user: 'requiresUser',
}

const getRequiredRole = ({ to, rolesDict }) => {
  let requiredRole = null

  for (let key in roles) {
    // if the required role is already set, then
    // don't do anything
    if (!requiredRole && to.matched.some(record => record.meta[rolesDict[key]])) {
      requiredRole = key
    }
  }
  // if no role is required, then the
  // return value is null (falsy)
  return requiredRole
}

// if fetched roles include the requiredRole
const routeAuthUser = ({ roles, requiredRole, toLogin, next }) => {
  if (!roles.includes(requiredRole)) {
    next(toLogin)
  } else {
    next()
  }
}

router.beforeEach((to, from, next) => {
  const requiredRole = getRequiredRole({to, rolesDict})

  // if requiredRole is falsy (this route
  // doesn't require a role), then go
  if (!requiredRole) {
    next()
  } else {
    const roles = fetchUserRoles()
    const toLogin = useToLoginObj(to)

    // if no roles are there, then go to login
    if (!roles || !roles.length) {
      next(toLogin)
    } else {
      // user is routed based on her/his role
      routeAuthUser({ roles, requiredRole, toLogin, next })
    }
  }
})

More verbose than the code in question, but

  • steps are broken up, so the logic shines through better
  • the order of beforeEach routing steps is more logical ("error first" approach)

I could not try it out, so there might be errors in the code, but the logic (I think) is clear: break it up to small pieces then construct the logic you want from those small pieces.

SUGGESTION

Try to find a different solution for storing user roles. localStorage is the least safe (even calling it "the least safe" is an exaggeration) solution for secure data.

  • Related