I am trying to redirect non-logged in user from all pages to /login
. I tried beforeEach()
but it doesn't fire when user enter site with direct url like /home
, /event
.
Per-Route Guard beforeEnter()
works perfectly since it fires once the user lands on that particular page. However, it requires me to add beforeEnter()
on every routes.
I am looking for a way to duplicate that beforeEnter()
on almost every page on the router (even on dynamic pages) which non-logged in user will be redirected to /login
.
This one works when user enter with direct url /home
.
routes: [
{
path: '/home',
name: 'home',
beforeEnter(to, from, next){
if ( to.name !== 'login' && !this.isloggedin ){
next({
path: 'login',
replace: true
})
} else {
next()
}
}
},
...
]
This one only works after user entered the site and route changed
vm.$router.beforeEach((to, from, next)=>{
if ( to.name !== 'login' && !this.isloggedin ){
next({
path: 'login',
replace: true
})
} else {
next();
}
})
Thanks in advance.
I am trying to redirect non-logged in user from all pages to /login
. I tried beforeEach()
but it doesn't fire when user enter site with direct url like /home
, /event
.
Per-Route Guard beforeEnter()
works perfectly since it fires once the user lands on that particular page. However, it requires me to add beforeEnter()
on every routes.
I am looking for a way to duplicate that beforeEnter()
on almost every page on the router (even on dynamic pages) which non-logged in user will be redirected to /login
.
This one works when user enter with direct url /home
.
routes: [
{
path: '/home',
name: 'home',
beforeEnter(to, from, next){
if ( to.name !== 'login' && !this.isloggedin ){
next({
path: 'login',
replace: true
})
} else {
next()
}
}
},
...
]
This one only works after user entered the site and route changed
vm.$router.beforeEach((to, from, next)=>{
if ( to.name !== 'login' && !this.isloggedin ){
next({
path: 'login',
replace: true
})
} else {
next();
}
})
Thanks in advance.
Share Improve this question edited Dec 8, 2020 at 16:11 Dan 63.1k18 gold badges109 silver badges118 bronze badges asked Dec 8, 2020 at 14:25 blackcityhenryblackcityhenry 7271 gold badge6 silver badges24 bronze badges2 Answers
Reset to default 9It looks like this beforeEach
is being defined inside an initialized component, which means the first routing has already occured. Define it in the router module with your routes instead:
const router = new VueRouter({
...
})
router.beforeEach((to, from, next)=>{
if ( to.name !== 'login' && !this.isloggedin ){
next({
path: 'login',
replace: true
})
} else {
next();
}
})
Hopefully you are using Vuex and can import the store for store.state.isloggedin
. If not using Vuex yet, this illustrates why it is useful for global state.
For a global and neat solution, you can control the router behavior in the App.vue
using the router.beforeResolve(async (to, from, next) => {});
.
beforeResolve is better than beforeEach, as beforeResolve will not load the component of the accessed path URL unless you fire manually the next function.
This is very helpful as you'll not render any interafce unless you check the authentication status of the user and then call next()
.
Example:
router.beforeResolve(async (to, from, next) => {
// Check if the user is authenticated.
let isUserAuthenticated = await apiRequestCustomFunction();
// Redirect user to the login page if not authenticated.
if (!isUserAuthenticated) {
location.replace("https://example.com/signin");
return false;
}
// When next() is called, the router will load the component corresponding
// to the URL path.
next();
});
TIP: You can display a loader while you check if the user is authenticated or not and then take an action (redirect to sign in page or load the app normally).