Soy muy principiante en JS y VUE. Hago mini CMS en Vue y Laravel. Creo este enrutador en 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 }, ] }, ] }Funciona bien, pero tengo 2 problemas:
Si el usuario está conectado, entonces la primera página (y la página principal) es /dashboard
¿Cómo puedo hacerlo?
Por favor, ayúdame.
Qué piensas de esto:
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 }) } } })Más detallado que el código en cuestión, pero
beforeEach de cada paso de enrutamiento es más lógico (enfoque "error primero")No pude probarlo, por lo que puede haber errores en el código, pero la lógica (creo) es clara: divídalo en partes pequeñas y luego construya la lógica que desea a partir de esas partes pequeñas.
Intente encontrar una solución diferente para almacenar roles de usuario. localStorage es la solución menos segura (incluso llamarla "la menos segura" es una exageración) para proteger los datos.