vuejs - 如果已经登录,则从登录/注册重定向到主页,如果在 vue-router 中未登录,则从其他页面重定向到登录

问题描述 投票:0回答:7

如果已登录并想要访问登录/注册页面,我想将用户重定向到主页;如果未登录并想要访问其他页面,我想将用户重定向到登录页面。有些页面被排除,这意味着不需要登录,所以我的代码就在下面:

router.beforeEach((to, from, next) => {
    if(
        to.name == 'About' ||
        to.name == 'ContactUs' ||
        to.name == 'Terms'
    )
    {
        next();
    }
    else
    {
        axios.get('/already-loggedin')
            .then(response => {
                // response.data is true or false
                if(response.data)
                {
                    if(to.name == 'Login' || to.name == 'Register')
                    {
                        next({name: 'Home'});
                    }
                    else
                    {
                        next();
                    }
                }
                else
                {
                    next({name: 'Login'});
                }
            })
            .catch(error => {
                // console.log(error);
            });
    }
});

但问题是它会陷入无限循环,例如每次加载登录页面并且用户未登录时,它都会将用户重定向到登录页面并再次重定向到登录页面......

我该如何解决这个问题?

vue.js vue-router
7个回答
55
投票

这就是我正在做的事情。首先,我使用

meta
数据作为路线,因此我不需要手动放置所有不需要登录的路线:

routes: [
  {
    name: 'About' // + path, component, etc
  },
  {
    name: 'Dashboard', // + path, component, etc
    meta: {
      requiresAuth: true
    }
  }
]

然后,我就有了这样的全局守卫:

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!store.getters.isLoggedIn) {
      next({ name: 'Login' })
    } else {
      next() // go to wherever I'm going
    }
  } else {
    next() // does not require auth, make sure to always call next()!
  }
})

这里我存储用户是否登录,并且不发出新请求。

在您的示例中,您忘记

Login
包含到“不需要身份验证”的页面列表中。因此,如果用户试图访问
Dashboard
,您发出请求,结果发现他没有登录。然后他转到
Login
,但是您的代码检查后发现它不是 3“auth not” 的一部分required”列表,然后再次拨打电话:)

因此跳过这个“清单”至关重要! ;)

祝你好运!


17
投票

如果有人仍在寻找答案,你可以颠倒逻辑。因此,与 requireAuth 一样,您将为经过身份验证的用户提供隐藏的路由。 (以 firebase 为例)

    routes: [{
            path: '/',
            redirect: '/login',
            meta: {
                hideForAuth: true
            }
        },
         {
            path: '/dashboard',
            name: 'dashboard',
            component: Dashboard,
            meta: {
                requiresAuth: true
            }
        }]

在你的 beforeEeach

router.beforeEach((to, from, next) => {
    firebase.auth().onAuthStateChanged(function(user) {
        if (to.matched.some(record => record.meta.requiresAuth)) {
            if (!user) {
                next({ path: '/login' });
            } else {
                next();
            }

        } else {
            next();
        }

        if (to.matched.some(record => record.meta.hideForAuth)) {
            if (user) {
                next({ path: '/dashboard' });
            } else {
                next();
            }
        } else {
            next();
        }
    });
});

1
投票

源自 @Andrey Popov 提供的答案。

我更喜欢明确禁止不需要身份验证的路由。这可以防止意外地不保护您的路由,即默认情况是重定向到登录页面

router.beforeEach((to, from, next) => {
  if (to.name === 'login') {
    next() // login route is always  okay (we could use the requires auth flag below). prevent a redirect loop
  } else if (to.meta && to.meta.requiresAuth === false) {
    next() // requires auth is explicitly set to false
  } else if (store.getters.isLoggedIn) {
    next() // i'm logged in. carry on
  } else {
    next({ name: 'login' }) // always put your redirect as the default case
  }
})

1
投票

这是非常基本的概念,使用

redirect:'/dashboard'
这样你就可以做到。您必须在您的路线列表中定义它。像这样。你可以忽略
mate: {}
。我用这个有不同的目的。

 routes: [ ....
           {
             path: '/login',
             name: 'login',
             component: LoginView,
             meta:{needAuth:false},
             redirect:'/dashboard'
           },
           {
            path: '/sign-up',
            name: 'sign-up',
            component: SignUpView,
            meta:{needAuth:false},
             redirect:'/dashboard'
          },
            {
             path: '/dashboard',
            name: 'dashboard',
            component: UserDashboard,
            meta:{needAuth:true},
            beforeEnter: ifAuthenticated,
          }
        ]

  

     function ifAuthenticated  (to, from, next)  {  store.test();
      if (localStorage.getItem("login-token")) { console.log("login done");
       next(); 
       return;
     }
      router.push({  name: 'login' });
    };

0
投票

除了Andrey的回答之外,如果您使用firebase身份验证,需要在main.ts中的createApp周围添加onAuthStateChanged。

firebase.auth().onAuthStateChanged((user) => {
  createApp(App).use(store).use(router).mount('#app')
})

0
投票

如何防止进入登录页面..在我的情况下,当用户登录时,当我按下后退按钮时,它不会进入登录页面,但只有几秒钟,它会显示在 URL /login 上,之后..它会重新加载主页网址..怎么办?在 vue 3 中


-1
投票
// requireAuth for those you want to authenticate 
// onlyGuest for  those you don't want to autenticate to open other thing if already 
//   logged in then it's redirect to home

 router.beforeEach((to,from,next)=>{
  if(to.matched.some(record => record.meta.requireAuth)){

    if(!store.state.loginUser){
      next({name:'Login'});
    }
    else{
      next();
    }
 }
else if (to.matched.some(record => record.meta.onlyGuest)) {

    if (store.state.loginUser && store.state.loginUser.token) {
        next({name: "Home"});
    } else {
        next();
    }
}
else{
  next();
}
 });
© www.soinside.com 2019 - 2024. All rights reserved.