I have a simple use case, where my application is using vue-router
and vuex
. Then store
contains a user
object which is null
in the beginning. After the user is validated from the server it sends back an user
object which contains a JWT
auth token which is assigned to the user
object in the store. Now lets assume that the user came back after 3 hours and tried to visit a route or perform any other action, considering that the auth token has expired by then, what would be the best way to check that(need to call axios post
to check it) and redirect user to the login
page. My app will have loads of components so I know I can write logic to check the token valid in the mounted
hook of each component but that would mean repeating it all of the components. Also I don't want to use the beforeEach
navigation guard because I cannot show any visual feedback to the user like checking...
or loading...
.
I do something similar in one of my projects, it's actually deceptively difficult to handle these types of situations, but you can add a beforeEnter
guard to your protected routes, then redirect if the authentication failed.
const guard = function(to, from, next) {
// check for valid auth token
axios.get('/api/checkAuthToken').then(response => {
// Token is valid, so continue
next();
}).catch(error => {
// There was an error so redirect
window.location.href = "/login";
})
};
Then on your route you can do:
{
path: '/dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
guard(to, from, next);
}
},
You may notice I've used location.href
rather than router.push
. I do that because my login form is csrf protected, so I need a new csrf_token.
Your other issue is going to be if the user tries to interact with your page without changing the route (i.e. they click a button and get a 401 response). For this I find it easiest to check authentication on each axios
request and redirect to login
when I receive a 401 response.
In terms of adding a loading spinner during the guard check you can simply add a loading flag to your vuex store then import your store into your router. Honestly though I wouldn't bother, on a decent production server the check will be done so quickly that the user is unlikely to ever see it.