i want to redirect to login if there's no token and the page route is not one of these:
router.beforeEach((to, from, next) => {
if (to.name !== ('loginregister.loginpage' || 'index.index' || 'products.index') && !store.state.token) next({ name: 'loginregister.loginpage' });
else next() })
this code restrict me from going to any path other than login
router.beforeEach((to, from, next) => {
if (to.name !== 'loginregister.loginpage' && to.name !== 'index.index' && to.name !== 'products.index' && !store.state.token) next({ name: 'loginregister.loginpage' });
else next() })
Propably this is what you are looking for.
Related
I am checking if jwt token is expired or not in my route guard. But it is running in an infinite loop. I can't understand why it is not working. Here are my codes:
Route Guard
const parseJwt = (token) => {
const base64Url = token.split('.')[1]
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
const jsonPayload = decodeURIComponent(Buffer.from(base64, 'base64').toString('ascii').split('')
.map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''))
return JSON.parse(jsonPayload)
}
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// need to login
if (localStorage.getItem('token') === null) {
next({
path: '/login',
params: { nextUrl: to.fullPath }
})
} else if (localStorage.getItem('token') && (parseJwt(localStorage.getItem('token')).exp < Date.now() / 1000)) {
console.log('token expired')
next({
path: '/login',
params: { nextUrl: to.fullPath }
})
} else {
next()
}
} else {
if (localStorage.getItem('token') && to.name === 'Login') {
return next({ path: '/' })
}
return next()
}
})
Only Login has requiresAuth as true in my routes.js.
{
path: '/login',
name: 'Login',
component: () => import('pages/auth/Login.vue'),
meta: { requiresAuth: false }
}
I cannot understand this part of code is returning an infinite loop:
next({
path: '/login',
params: { nextUrl: to.fullPath }
})
Please any help is very much appreciated.
Thank you
I think the problem is here
if (localStorage.getItem('token') && to.name === 'Login') {
return next({ path: '/' })
}
Let's assume I have the token but it's expired. The navigation guard will redirect me to login page, which will redirect me to the home page (because it only checks the token existence and thinks i'm authenticated), which will once again redirect me to login page... And here is our infinite loop
So you should also check if the token has expired in this condition:
const token = localStorage.getItem('token')
const isExpiredToken = parseJwt(token).exp < Date.now() / 1000
if (token && !isExpiredToken && to.name === 'Login') {
return next({ path: '/' })
}
When users reload a page (that is not the / route) they should be redirected to /. I've tried this but that ends up in an infinite loop:
router.beforeEach((to, from, next) => {
if (from.path === '/' && to.path !== '/' && store.state.loggedIn) {
next()
} else {
next('/')
}
})
from path and to path together are causing the infinite loop
basically do this
router.beforeEach((to, from, next) => {
if (!store.state.loggedIn && to.path !== '/') {
next('/')
}
})
Need to do something like middleware, need to check if the user has a token, then allow the transition
router.beforeEach((to, from, next) => {
const accessNeed = ['Dashboard',]
if (localStorage.getItem("token")){
if (!accessNeed.includes(to.name)) {
next({ name: 'Home' })
}else{
next()
}
}else{
next()
}
})
You are either using Nuxt, or just the Vue SSR package. So you have to make sure, the code gets executed only on client:
router.beforeEach((to, from, next) => {
if (!process.client) {
next()
return
}
const accessNeed = ['Dashboard']
if (window && window.localStorage.getItem("token")){
if (!accessNeed.includes(to.name)) {
next({ name: 'Home' })
} else{
next()
}
}
next()
})
I have a question about VueJS and the form of authentication it has, I am trying to perform a multi auth guard with beforeEnter but it does not work, I leave a job on how I want to do it to see if they can help me.
const isGlobal = (to, from, next) => {
console.log('isGlobal called');
if (store.getters.isAuthenticated && store.getters.getProfile.is_global) {
next();
return
}
next(false )
}
const isAdmin = (to, from, next) => {
console.log('isAdmin called');
if (store.getters.isAuthenticated && store.getters.getProfile.is_admin) {
next();
return
}
next(false)
}
const isSupervisor = (to, from, next) => {
console.log('isSupervisor called');
if (store.getters.isAuthenticated && store.getters.getProfile.is_supervisor) {
next();
return
}
next(false)
}
const routes = [{
path: '/',
name: 'login',
component: Login,
beforeEnter: [isSupervisor || isGlobal || isAdmin],
}
];
Thank you
The problem is that [isSupervisor || isGlobal || isAdmin] is an array equals to [false] or [true], it must be a function. Try something like this:
const isGlobal = store.getters.isAuthenticated && store.getters.getProfile.is_global
const isAdmin = store.getters.isAuthenticated && store.getters.getProfile.is_admin
const isSupervisor = store.getters.isAuthenticated && store.getters.getProfile.is_supervisor
const conditionalNext = function(condition) {
return (to, from, next) => {
if (condition) {
next();
return
}
next(false)
}
}
const routes = [{
path: '/',
name: 'login',
component: Login,
beforeEnter: conditionalNext(isSupervisor || isGlobal || isAdmin)
}
];
I have a simple vue app that I am trying to protect some routes, Ie.: if user is logged in show the dashboard page and block the member-login page. If the user is NOT logged in show the member-login page but block the dashboard page.
It is working on the navigation... so if I am not logged in and click "dashboard" I get redirected to the member-login page. And if I am logged in and click "login" I get redirected to the dashboard page. Cool.
Except if I type the path in the address bar, meaning, if I am logged in and click "login" I get redirected to the dashboard, but if I type /member-login in the address bar it still takes me to the member-login page, and it shouldn't. Same in reverse with the dashboard page if I am not logged in.
I am using the beforeEach() method to perform the guards, and here is what I have:
router.beforeEach((to, from, next) => {
let ls = JSON.parse(localStorage.getItem('loggedInMember'));
if(ls === null && to.name === 'dashboard'){
next('/member-login');
} else if ( ls !== null && to.name === 'login') {
next('/dashboard');
} else {
next();
}
});
I should mention that this is a global guard, and it lives in the main.js file of my project.
What am I missing?
Thanks so much!
So, the issue was a stupid mistake on my part...
I had the router.beforeEach method below the new Vue({}) method and it didn't like that. So moving the beforeEach method above the new Vue method fixed this issue.
Buggy:
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
router.beforeEach((to, from, next) => {
let ls = JSON.parse(localStorage.getItem('loggedInMember'));
if(ls === null && to.name === 'dashboard'){
next('/member-login');
} else if ( ls !== null && to.name === 'login') {
next('/dashboard');
} else {
next();
}
});
Fixed:
router.beforeEach((to, from, next) => {
let ls = JSON.parse(localStorage.getItem('loggedInMember'));
if(ls === null && to.name === 'dashboard'){
next('/member-login');
} else if ( ls !== null && to.name === 'login') {
next('/dashboard');
} else {
next();
}
});
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
You mean you input the /member-login and it takes you to the login page ? It seems to me that it's the right action , or there's some misunderstanding I get?
Can you provide more details ?