Home > database >  Infinite redirection using middleware
Infinite redirection using middleware

Time:09-15

I'm trying to implement simple middleware logic and got

Detected an infinite redirection in a navigation guard when going from "/" to "/login". Aborting to avoid a Stack Overflow. This will break in production if not fixed.

I know that somewhere in my code it redirects more than once, but cannot find where.

Here is the router:

import { createWebHistory, createRouter } from 'vue-router'
import store from '@/store'

/* Guest Component */
const Login = () => import('@/components/Login.vue')
const Register = () => import('@/components/Register.vue')
/* Guest Component */

/* Layouts */
const DahboardLayout = () => import('@/components/layouts/Default.vue')
/* Layouts */

/* Authenticated Component */
const Dashboard = () => import('@/components/Dashboard.vue')
/* Authenticated Component */


const routes = [
    {
        name: "login",
        path: "/login",
        component: Login,
        meta: {
            middleware: "guest",
            title: `Login`
        }
    },
    {
        name: "register",
        path: "/register",
        component: Register,
        meta: {
            middleware: "guest",
            title: `Register`
        }
    },
    {
        path: "/",
        component: DahboardLayout,
        meta: {
            middleware: ["all"]
        },
        children: [
            {
                name: "dashboard",
                path: '/',
                component: Dashboard,
                meta: {
                    title: `Dashboard`
                }
            }
        ]
    }
]

const router = createRouter({
    history: createWebHistory(),
    routes, // short for `routes: routes`
})

router.beforeEach((to, from, next) => {
    document.title = to.meta.title
    if (to.meta.middleware == "all") {
        return next();
    } else if (to.meta.middleware == "guest") {
        if (store.state.auth.authenticated) {
            return next({ name: "login" })
        } else {
            return next()
        }
    } else if (to.meta.middleware == "auth") {
        if (store.state.auth.authenticated) {
            return next()
        } else {
            return next({ name: "login" })
        }
    }
})

export default router

And in Default.vue component:

<router-link :to="{name:'login'}">Login</router-link>

CodePudding user response:

Every time you redirect in the beforeEach navigation guard the new route will also have to go through the navigation guard. The infinite loop is from trying to redirect to the login route, and always hitting this code:

else if (to.meta.middleware == "guest") {
        if (store.state.auth.authenticated) {
            return next({ name: "login" })

So you redirect to login, which redirects to login, which redirects... etc. You need to add some other condition to just return next() when going to the login route in this situation, maybe like this:

router.beforeEach((to, from, next) => {
  document.title = to.meta.title;
  if (to.meta.middleware == 'all' || to.name === 'login') {
    return next();
  }
  ...

CodePudding user response:

Based on @DaveNewton questions I changed it like that and it works fine:

router.beforeEach((to, from, next) => {
    document.title = to.meta.title
    if (to.meta.middleware == "all") {
        return next();
    } else if (to.meta.middleware == "guest") {
        if (!store.state.auth.authenticated) {
            return next()
        }
    } else if (to.meta.middleware == "auth") {
        if (store.state.auth.authenticated) {
            return next()
        } else {
            return next({ name: "login" })
        }
    }
})
  • Related