I'm working on a Vue.js application and I need to implement router guards to limit access based on user role and prevent an unlogged user to access the application.
The login process involves an external application (WSO2 Identity Server, specifically), and the user info retrieved are saved in a Vuex store.
The problem is that the login function is asynchronous, therefore when the router guards are executed user infos aren't available yet. To make it work I called the login function inside an anonymous async function and I put the guards inside its then
block.
Since I didn't find examples of this approach on the internet, I would like to know if it is correct or there is a better way of handling this problem. Thank you all in advance.
Here's an example of my router code:
... router code
(async function() {
// get user data and saves them in the vuex store
await userService.initUserData();
})().then( function() {
const isAuthenticated = store.getters.getIsAuthenticated;
const userRole = store.getters.getUserRole;
router.beforeEach((to, from, next) => {
// check if user is logged in,
// if not redirect to login page (LoginPage)
if (to.name !== 'LoginPage' && !isAuthenticated) {
next({ name: 'LoginPage' });
} else {
if (to.meta.customerAuth) {
if (userRole === 'Customer') {
next();
} else if (userRole === 'Admin') {
next({ name: 'AdminView' });
} else {
next({ name: 'LoginPage' });
}
} else if (to.meta.adminAuth) {
if (userRole === 'Admin') {
next();
} else if (userRole === 'Customer') {
next({ name: 'CustomerView' });
} else {
next({ name: 'LoginPage' });
}
}
}
})
}
);
You should persist your user informations in the localstorage so you don't need to fetch permissions everytime you refresh the page.
What you can do if permissions would happen to change for the validity of a token is to return a 401 HTTP code that would logout and redirect to login to get a new token with the new permissions.
As you store your user infos in storage you don't need to wait to configure your guards.
The point is: login should only happen once, if you refresh you shouldn't have to login again