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路由器。。。需要对历史模式进行不同的调整。答案应该用这些细节来说明。如果你正在使用身份验证,你可以像这样定义重定向URLconst redirectUrl=to.redirectedFrom代码>,然后使用