Home > Back-end >  Maximum call stack size exceeded - Vue Router
Maximum call stack size exceeded - Vue Router

Time:07-18

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