Redirect 使用vue路由器登录后重定向到请求的页面

Redirect 使用vue路由器登录后重定向到请求的页面,redirect,vue.js,vuejs2,vue-router,Redirect,Vue.js,Vuejs2,Vue Router,在我的应用程序中,某些路由仅可供经过身份验证的用户访问。当未经身份验证的用户单击必须登录的链接时,他将被重定向到登录组件。 如果用户成功登录,我想将他重定向到他必须登录之前请求的URL。但是,如果用户在登录之前没有请求另一个URL, 如何使用vue路由器实现这一点? 登录后不重定向的我的代码 router.beforeEach( (to, from, next) => { if(to.matched.some(record => record.meta.for

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

如果用户成功登录,我想将他重定向到他必须登录之前请求的URL。但是,如果用户在登录之前没有请求另一个URL,

如何使用vue路由器实现这一点?

登录后不重定向的我的代码

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


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

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('/')
          })



我将非常感谢任何形式的帮助

这可以通过在路由中添加重定向路径来实现

然后在登录时,必须检查是否设置了重定向参数:
-如果设置重定向到param中找到的路径
-如果设置的是而不是,则可以回退根目录。


对链接执行操作,例如:

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

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()
        }
    }        
)
submitForm() {
  AuthService.login(this.credentials)
    .then(() => this.$router.push(this.$route.query.redirect || '/'))
    .catch(error => { /*handle errors*/ })
}
希望能有所帮助。

并且登录功能是

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
  })

我知道这很古老,但这是谷歌的第一个结果,对于那些只想得到它的人来说,这是你添加到两个文件中的内容。在我的例子中,我使用firebase进行身份验证

路由器 这里的关键行是
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)它将它们发送到前面生成的查询url

signIn() {
      firebase.auth().signInWithEmailAndPassword(this.email, this.password).then(
        (user) => {
          this.$router.replace(this.$route.query.from);
        },
        (err) => {
          this.loginerr = err.message;
        },
      );
    },

我将更详细地充实这一逻辑,但它是按原样工作的。我希望这能帮助那些看到这一页的人。

这将帮助你@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()
    }
);

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

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

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


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

    login.vue
    //如果用户登录成功,请将他们路由到他们以前请求的路径或某个默认路径。$router.push(localStorage.getItem('pathtoadeafterlogin')| |'somedefaultroute')


  • 根据Matt C的回答,这可能是最简单的解决方案,但该帖子存在一些问题,因此我认为最好编写一个完整的解决方案

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

    在路由器的beforeach钩子中,在会话存储中设置目标路径,以便在身份验证后可以检索该路径。如果您通过第三方身份验证提供商(谷歌、Facebook等)重定向,也可以这样做

    router.js

    //如果用户未通过身份验证,则在重定向到每次登录之前

    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

    在您的登录方法中,经过身份验证后,您将有一行代码将用户发送到不同的路由。这一行现在将从会话存储中读取值。之后,我们将从会话存储中删除该项,以便将来不会意外使用它(例如,如果您允许用户直接进入下一次身份验证的登录页面)

    更完整的示例可能如下所示:

    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.replace(sessionStorage.getItem('redirectPath') || '/defaultpath');
    
            //Cleanup redirectPath
            sessionStorage.removeItem('redirectPath');
    
          }).catch(err => {
            console.log(err);
          });
        },
      },
    });
    
    这对我有用

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

    如果路线防护设置如下所示

    router.beforeach((to,from,next)=>{
    if(to.matched.some(record=>record.meta.requireAuth)){
    如果(!loggedIn){
    下一个({
    路径:“/login”,
    查询:{重定向:到.fullPath}
    });
    }否则{
    next();
    }
    }否则{
    next();
    }
    
    });
    您可以执行类似于
    next({path:'/login?from='+to.path})
    的操作,然后检查登录页面上是否设置了
    from
    query参数,并执行以下操作:redirect@FlorianHaider这听起来是一个很好的解决方案!如何检查是否从我的登录组件设置了from查询参数?@Schwesi您可以使用
    this.$route.query.from
    获取查询参数。如果没有查询,您将得到一个空的object@VamsiKrishna伟大的非常感谢。为我工作,很好的回答。。。我尝试了很多其他方法来解决这个问题,比如将url存储在localstorage中等等。。但这是一种简洁且正确的方法来验证重定向。我认为这是最普遍的解决方案,但我需要进一步完善它。我无法简单地在
    window.location.pathname
    上执行
    $router.replace
    ,其中包括整个URL(
    http://...
    )。我需要获取
    window.location.hash
    并在设置
    from
    查询参数的
    之前去掉前导的
    #/
    。当然,我正在哈希模式下使用vue路由器。。。需要对历史模式进行不同的调整。答案应该用这些细节来说明。如果你正在使用身份验证,你可以像这样定义重定向URL
    const redirectUrl=to.redirectedFrom,然后使用