使用vue-router

时间:2017-08-24 08:44:15

标签: redirect vue.js vuejs2 vue-router

在我的应用程序中,只有经过身份验证的用户才能访问某些路由。
当未经身份验证的用户点击必须登录的链接时,他将被重定向到登录组件。

如果用户成功登录,我想将他重定向到他必须登录之前请求的网址。但是,也应该有默认路由,以防用户在登录前没有请求其他URL。

如何使用vue-router实现此目的?


我的代码在登录后没有重定向

router.beforeEach(
    (to, from, next) => {
        if(to.matched.some(record => record.meta.forVisitors)) {
            next()
        } else if(to.matched.some(record => record.meta.forAuth)) {
            if(!Vue.auth.isAuthenticated()) {
                next({
                    path: '/login'
                    // Redirect to original path if specified
                })
            } else {
                next()
            }
        } else {
            next()
        }
    }        
)



我的登录组件中的登录功能

login() {
    var data = {
        client_id: 2,
        client_secret: '**************',
        grant_type: 'password',
        username: this.email,
        password: this.password
    }
    // send data
    this.$http.post('oauth/token', data)
         .then(response => {
             // authenticate the user
             this.$auth.setToken(response.body.access_token,
             response.body.expires_in + Date.now())
             // redirect to route after successful login
             this.$router.push('/')
          })



我会非常感谢任何帮助!

8 个答案:

答案 0 :(得分:22)

以一种不同的方式,这可以通过在您想要重定向时在路由中添加查询参数来实现,然后在设置参数时检查您何时登录;如果已设置,则使用它或以其他方式回溯根目录。

在代码中应该看起来像这样:

对您的链接执行操作,例如:

onLinkClicked() {
  if(!isAuthenticated) {
    // If not authenticated, add a path where to redirect after login.
    this.$router.push({ name: 'login', query: { redirect: '/path' } });
  }
}

登录提交操作

submitForm() {
  AuthService.login(this.credentials)
    .then(() => this.$router.push(this.$route.query.redirect || '/'))
    .catch(error => { /*handle errors*/ })
}

希望它有所帮助。

答案 1 :(得分:6)

我知道这很旧,但这是google的第一个结果,对于那些只希望将其提供给您的人来说,这就是您添加到两个文件中的结果。就我而言,我正在使用Firebase进行身份验证。

路由器

这里的关键行是<?php $arr[0][]=array('2018-06-13'=>"hadir"); $arr[0][]=array('2018-06-12'=>"hadir"); $arr[0][]=array('2018-06-11'=>"alfa"); $arr[1][]=array('2018-06-13'=>"hadir"); $arr[1][]=array('2018-06-12'=>"hadir"); $arr[1][]=array('2018-06-11'=>"hadir"); print_r($arr); for($i=0;$i<count($arr);$i++){ for($j=0;$j<count($arr[$i]);$j++){ foreach($arr[$i][$j] as $k=>$v){ $newarr[$i][$k]=$v; } } } print_r($newarr); ?> ,在这里我得到他们第一次访问的相对路径,然后在查询中通过下一行const loginpath = window.location.pathname;作为重定向中的查询。

next({ name: 'Login', query: { from: loginpath } });

登录页面

这没什么好奇怪的,您会在对用户进行身份验证router.beforeEach((to, from, next) => { const currentUser = firebase.auth().currentUser; const requiresAuth = to.matched.some(record => record.meta.requiresAuth); if (requiresAuth && !currentUser) { const loginpath = window.location.pathname; next({ name: 'Login', query: { from: loginpath } }); } else if (!requiresAuth && currentUser) next('menu'); else next(); }); 时注意到我的操作,它将其发送到我们之前生成的查询网址。

this.$router.replace(this.$route.query.from);

我将更详细地阐述这种逻辑,但它仍然可以正常工作。希望这对访问该页面的人有所帮助。

答案 2 :(得分:2)

根据Matt C的回答,这可能是最简单的解决方案,但是那篇文章有一些问题,所以我认为最好写一个完整的解决方案。

目标路由可以存储在浏览器的会话存储中,并在身份验证后进行检索。在这种情况下,使用会话存储而不是使用本地存储的好处是,在结束浏览会话后数据不会保留。

在路由器的beforeEach钩子中,将会话路径设置为会话存储中的目标路径,以便在身份验证后可以对其进行检索。如果您是通过第三方身份验证提供程序(Google,Facebook等)重定向的,则此方法也适用。

router.js

//如果用户未通过身份验证,则在重定向以登录到beforeEach

之前
sessionStorage.setItem('redirectPath', to.path)

因此,更完整的示例可能看起来像这样。我在这里使用Firebase,但如果您不是,则可以根据需要进行修改:

router.beforeEach((to, from, next) => {
  const requiresAuth = to.matched.some(x => x.meta.requiresAuth);
  const currentUser = firebase.auth().currentUser;

  if (requiresAuth && !currentUser) {
    sessionStorage.setItem('redirectPath', to.path);
    next('/login');
  } else if (requiresAuth && currentUser) {
    next();
  } else {
    next();
  }
});

login.vue

在登录方法中,经过身份验证后,您将获得一行代码,该代码会将用户发送到其他路由。现在,此行将从会话存储中读取值。然后,我们将从会话存储中删除该项目,以便将来不会意外使用该项目(例如,如果用户直接转到下一个身份验证的登录页面)。

this.$router.push(sessionStorage.getItem('redirectPath') || '/defaultpath');
sessionStorage.removeItem('redirectPath');

一个更完整的示例可能看起来像这样:

export default Vue.extend({
  name: 'Login',
  data() {
    return {
      loginForm: {
        email: '',
        password: ''
      }
    }
  },
  methods: {
    login() {
      auth.signInWithEmailAndPassword(this.loginForm.email, this.loginForm.password).then(user => {

        //Go to '/defaultpath' if no redirectPath value is set
        this.$router.push(sessionStorage.getItem('redirectPath') || '/defaultpath');

        //Cleanup redirectPath
        sessionStorage.removeItem('redirectPath');

      }).catch(err => {
        console.log(err);
      });
    },
  },
});

答案 3 :(得分:1)

另一个快捷而肮脏的选择是使用本地存储,如下所示:

  1. 在您的beforeEach中,在重定向到登录之前,请放置以下代码行,以将初始请求的路径保存到本地存储中:

    router.js
    //如果用户未通过身份验证,则在重定向到登录名之前
    localStorage.setItem('pathToLoadAfterLogin', from.path)

  2. 然后在登录组件中,成功登录后,可以重定向到先前创建的localStorage变量:

    login.vue
    // 如果用户登录成功,请将其路由到他们先前请求的内容或某些默认路由
    this.$router.push(localStorage.getItem('pathToLoadAfterLogin') || 'somedefaultroute');

答案 4 :(得分:1)

如果按以下步骤设置了路由保护器

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (!loggedIn) {
            next({
                path: "/login",
                query: { redirect: to.fullPath }
            });
        } else {
            next();
        }
    } else {
        next();
    }
});

可以在成功登录后提取并使用重定向查询

let searchParams = new URLSearchParams(window.location.search);

if (searchParams.has("redirect")) {
  this.$router.push({ path: `${searchParams.get("redirect")}` });
} else this.$router.push({ path: "/dashboard" });

答案 5 :(得分:0)

Much easier with this library 和登录功能是

let redirect = this.$auth.redirect();
this.$auth
  .login({
    data: this.model,
    rememberMe: true,
    redirect: { name: redirect ? redirect.from.name : "homepage",  query: redirect.from.query },
    fetchUser: true
  })

答案 6 :(得分:0)

这将帮助您@Schwesi。

Router.beforeEach(
    (to, from, next) => {
        if (to.matched.some(record => record.meta.forVisitors)) {
            if (Vue.auth.isAuthenticated()) {
                next({
                    path: '/feed'
                })
            } else
                next()
        }
        else if (to.matched.some(record => record.meta.forAuth)) {
            if (!Vue.auth.isAuthenticated()) {
                next({
                    path: '/login'
                })
            } else
                next()
        } else
            next()
    }
);

答案 7 :(得分:0)

这对我有用。

 this.axios.post('your api link', {
                token: this.token,              
            })
                .then(() => this.$router.push(this.$route.query.redirect || '/dashboard'))