On page reload: Redirect all routes to '/' - vue-router

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('/')
}
})

Related

Maximum call stack size exceeded - Vue Router

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: '/' })
}

Vue 2 router in beforeEach localStorage is not defined

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()
})

How to set multiple route name into vue guard beforeEach function

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.

Error: Redirected when going from "/pages/login" to "/dashboard" via a navigation guard

Guys i don't know why im get this error when i try to login, console error after login is made:
Error: Redirected when going from "/pages/login" to "/dashboard"
via a navigation guard.
Im trying when i hit login to redirect me to /dashboard page after the validation is made but when i hit login it does nothing no redirect, and if i hit again the login button the redirect is made on dashboard page. Any solutions? Thanks!
loginJWT ({ commit }, payload) {
return new Promise((resolve, reject) => {
jwt.login(payload.email, payload.password)
.then(response => {
console.log(response.data)
// If there's user data in response
if (response.data.userDetails) {
// Navigate User to homepage
router.push(router.currentRoute.query.to || '/') // <- Here is the redirect after login
// Set accessToken
localStorage.setItem('accessToken', response.data.accessToken)
// Update user details
commit('UPDATE_USER_INFO', response.data.userDetails, {root: true})
// Set bearer token in axios
commit('SET_BEARER', response.data.accessToken)
resolve(response)
} else {
reject({message: 'Wrong Email or Password'})
}
})
.catch(error => { reject(error) })
})
}
In router js:
{
path: '/dashboard',
name: 'dashboard',
component: () => import('./views/Dashboard.vue'),
meta: {
rule: 'editor',
authRequired: false
},
beforeEnter: (to, from, next) => {
guard(to, from, next)
}
}
And the guard code that validate the token after each route:
const guard = function (to, from, next) {
// check for valid auth token
const token = localStorage.getItem('accessToken')
axios.post('http://localhost:8081/api/users/checkAuthToken', {tokn: token})
.then(function (response) {
if (response.status === 200) {
next()
}
}).catch(function (error) {
if (error.response && error.response.status === 401) {
alert('access neautorizat')
next('/pages/login')
localStorage.removeItem('userInfo')
localStorage.removeItem('accessToken')
}
})
}
beforeEach code:
router.beforeEach((to, from, next) => {
const publicPages = [
'/pages/login',
'/pages/register',
'/pages/forgot-password',
'/pages/comingsoon',
'/pages/error-404',
'/pages/error-500',
'/pages/not-authorized',
'/pages/maintenance',
'/callback'
]
const authRequired = !publicPages.includes(to.path)
const loggedIn = localStorage.getItem('accessToken')
if (authRequired && !loggedIn) {
return next('/pages/login')
}
return next()
})
First Set accessToken and Last Navigate User to homepage

Multi Auth Guard VueJS Vue-Route Vuex

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)
}
];