Error message "Exceeded the maximum call stack size" encountered during Vue-router authentication

I am currently in the process of developing a dashboard using Vue, Vuex, and Quasar. However, I have encountered an authentication error that is preventing me from progressing. Additionally, I need assistance in ensuring that when a user is already logged in, they are redirected directly to the dashboard.

The login functionality appears to be working perfectly fine. Upon entering credentials and logging in, the token is received and stored correctly in the status. However, the issue arises when trying to redirect to the dashboard after login. Instead, I receive the following error message (screenshot attached): https://i.stack.imgur.com/IhLbw.png Router Index

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '../store'
import routes from './routes'

Vue.use(VueRouter)

// Router setup

const Router = new VueRouter({
  scrollBehavior: () => ({ x: 0, y: 0 }),
  routes,
  mode: process.env.VUE_ROUTER_MODE,
  base: process.env.VUE_ROUTER_BASE
})

// Navigation Guard

Router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (store.getters['auth/isLoggedIn']) {
      next({ name: 'Dashboard' })
      return
    }
    next('/login')
  } else {
    next()
  }
})

export default Router

Routes

const routes = [
  { path: '/login', name: 'Login', component: () => import('pages/Login.vue') },
  {
    path: '/app',
    component: () => import('layouts/MainLayout.vue'),
    meta: { requiresAuth: true },
    name: 'App',
    children: [
      { path: 'dashboard', name: 'Dashboard', component: () => import('pages/Index.vue') },
      { path: 'user', name: 'User', component: () => import('pages/User.vue') }
    ]
  },

  {
    path: '*',
    component: () => import('pages/Error404.vue')
  }
]

export default routes

Vuex Auth

import Api from '../api'

// Vuex module for auth

export default {
  namespaced: true,
  state: {
    token: localStorage.getItem('token') || '',
    user: null
  },
  getters: {
    isLoggedIn: state => !!state.token,
    user (state) {
      return state.user
    }
  },
  mutations: {
    SET_TOKEN (state, token) {
      state.token = token
    },
    SET_USER (state, user) {
      state.user = user
    }
  },
  actions: {
    async signIn ({ commit }, credentials) {
      const response = await Api().post('/token', credentials)
      const token = response.data.token
      const loginuser = {
        username: response.data.user_display_name,
        email: response.data.user_email
      }
      commit('SET_TOKEN', token)
      commit('SET_USER', loginuser)
    },
    signOut ({ commit }) {
      return Api().post('/logout').then(() => {
        commit('SET_TOKEN', null)
        commit('SET_USER', null)
      })
    }

  }
}

Answer №1

The issue may lie with the beforeEach guard in your code snippet:

Router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (store.getters['auth/isLoggedIn']) {
      next({ name: 'Dashboard' })
      return
    }
    next('/login')
  } else {
    next()
  }
})

Your application seems to be stuck in an infinite loop due to the continuous redirection to the 'Dashboard' route. This routing cycle repeats indefinitely because each visit triggers the beforeEach function, leading to subsequent redirects back to 'Dashboard'. This behavior eventually results in an exception being raised.

Answer №2

Using guards is a common practice to restrict unauthorized users from accessing certain routes, as you already know. However, the issue arises when, as Andrea pointed out, continuous redirection to the same page creates a loop due to the beforeEach function being triggered each time.

Instead of this repetitive behavior, it's advisable that once a user is authorized, you simply allow them to proceed by calling next(), or redirect them to a specific location such as "/login" if they are not authorized.

My suggestion would be to set your Dashboard as the default route using the route redirect property like so:

{ path: '/app', redirect: '/dashboard' }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble with the import of the directory's index file?

The code snippet in application.js indicates that the "home" imported from "./routes/index" is undefined. import {home} from "./routes/index" console.log(JSON.stringify(home, null, 4)) This is what index.js contains: export * from "./home.js" And here ...

Enhancing UI design with Vue.js

I'm attempting to customize elements using data from a JSON file in Vue.js: <div v-for="(item, index) in json._items" class="help-inner-callout" v-html="item.text" style="top:item.top; left: item.left;">&l ...

How can I effectively send a form with the value of 'put' using Laravel and Ajax?

I have been working on a function that utilizes AJAX to validate and send responses to the view when an edit form is submitted. However, I am encountering an issue where the page loads on a new URL like localhost:8000/comment/id, and I want the page to dis ...

Unable to interact with buttons located in the title bar of the Electron application

I am currently working on developing a basic Text Editor using Electron. I am facing an issue with adding a custom title bar where the buttons are not clickable. To try and fix this issue, I have included an onclick tag to the buttons in my code. main.js ...

When using $state.go in $stateChangeStart, there is a dual state transition in ui-router

Take a look at my Plunker. When you click on the profile link and examine the list of state changes: stateChanges = [ " -> home", "home -> profile", "home -> signIn", "signIn -> signIn" ] You'll notice an unexpected extra state c ...

The route parameters seem to be malfunctioning when using the Google Maps Directions API

Currently, I am attempting to transfer the latitude and longitude of a location from one HTML file to another using the $routeParams feature. In the second HTML file, I utilized the Google Maps directions API to display the directions from the source lati ...

Ways to combine and run the outcomes of several functions with Lodash

Imagine you have two distinct functions (or more) that take one argument from an executor and return the result object. Let's illustrate this with an example: const style_1 = theme => ({ header : { color : theme.primary } }) const sty ...

Leverage the Axios package to make requests within a for loop

I'm new to JavaScript and currently working on a project using Vue.js, Axios, and the API available at . The goal of this project is to retrieve NBA player statistics for a homework assignment. I could use some assistance in addressing certain issues. ...

Is Axios the sole option for API calls when utilizing Next.js with SSG and SSR?

Can someone clarify the best practice for data fetching in Next.js? Should we avoid using axios or other methods in our functional components, and instead rely on SSG/SSR functions? I'm new to Next.js and seeking guidance. ...

Retrieve the value of an input text within a table data cell using JavaScript

I have set up a table using CGridView, which includes input text fields for user input. The problem I'm facing is that I can retrieve the text from table cells without input fields, but not from those containing input fields. PHP: <?php $this-> ...

Tips for creating a high-performing algorithm to locate a specific word within a JSON file

I am in the process of creating a word game that involves users typing letters on a board to form meaningful words. If the typed word matches any word in a JSON file, the user earns a point. I have successfully implemented the basic functionalities of the ...

When using an `if` statement in CSS to determine if the value of `left` is

Is there a way to trigger an event only when the object reaches a specific percentage of its left position? I am trying to achieve this using jQuery with the .css() method. Here is what I have so far: HTML: <div id="midDiv"><img ..../></di ...

Customizing translations for various domains in Vue-i18n

Our app has a global reach and our company is undergoing a rebranding process in certain markets. For instance, we are currently known as "Acme Company" in the U.S. and Canada, but now we aim to be recognized as "Acme Company" in the U.S. and "Foo Company ...

Trigger the .focus() method on a neighboring VueJS Component

I am facing an issue with two independent components in my Vue instance. I have a select component and an input component, both of which are siblings. I need to trigger a focus event on the input component when the select component is changed. Since both ...

What is the process for creating a React Component with partially applied props?

I am struggling with a function that takes a React component and partially applies its props. This approach is commonly used to provide components with themes from consumers. Essentially, it transforms <FancyComponent theme="black" text="blah"/> int ...

What is the best way to navigate through an XML document within the DOM of an HTML

I am facing an issue with HTML code. My goal is to navigate through an XML document directly from within the HTML code. Here is the XML code: <?xml version = "1.0"?> <planner> <year value = "2000"> <date month = "7" day = " ...

An elementary React project facing compilation issues

I'm currently exploring react hooks, but I encountered an error with the useReducer hook. The console displays the following error message: "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happe ...

Guide to developing a personalized useReducer with integrated decision-making and event activation

I am interested in creating a custom hook called useTextProcessor(initialText, props). This hook is designed for managing and manipulating text (string) within a React state. It utilizes useReducer to maintain a cumulative state. Here is the implementation ...

Node.js Timer Functionality for Precision Timing

I'm currently in the process of developing a live chess application and one feature I'm looking to incorporate is a timer. The challenge I'm facing lies in ensuring the timer is accurate. After conducting various tests, I discovered that bot ...

Counting the elements on a page using Selenium and Node.js: A step-by-step guide

I've been experimenting with Selenium in Javascript using NodeJS and I'm trying to tally up some elements based on CSS selectors. So far, I've attempted a few methods: client.findElements(By.css(".some-class")).size(); However, I encounte ...