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