Reputation: 727
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.
Upvotes: 9
Views: 44870
Reputation: 681
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).
Upvotes: 0
Reputation: 63069
It 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.
Upvotes: 9