1

I have a vue.js app that makes API requests with axios and passes some authorization token in the request headers. If authorization token expires within some time period API calls fail with code 401 and my app shows login page where the user enters login and password and thus the app gets a new authorization token and continue to work.

Probably there is a better solution, but currently my idea is to handle authorization token expiration in this way: if I get 401 error I completely reset the app (including its state and, what is more important, all axios requests that still are in progress) then I show login page and reinitialize the app when the user presses 'login' button. To implement this scenario I need a way to immediately interrupt all the current app activity as if the page is reset by user with F5 button. Is it possible and is it a good idea to do this?

EDIT1: what if I do window.location.reload()?

Alexey Starinsky
  • 3,699
  • 3
  • 21
  • 57
  • you can use eventBus to pass a custom event such as 'reset-app' to all your components, and define data-reseting method on each one of them, to be called like this: `this.$events.$on('reset-app',this.resetComponent(params));` thats how you do it on eventBus in vue: https://alligator.io/vuejs/global-event-bus/ – Efrat Levitan Nov 09 '18 at 12:00
  • @Efrat it is too complicated, I simply need to stop the app (something like std::terminate() in C++). – Alexey Starinsky Nov 09 '18 at 12:50
  • hmmm... if you want to reset a single component, you just have to add it a v-if directive on its parent component. maybe its possible to put `v-if="flag"` on the router-link tag in the app.vue? if its possible, your whole application will get destroyed and re-start, by a simple function: `this.flag=false; this.flag=true;`. but i have to admit, it sounds a bit hacky. – Efrat Levitan Nov 09 '18 at 13:02
  • @Efrat there is a separate .js file with 'export default new Router({...' that is used with 'import router from ...' and there are tags in App.vue. Where to put 'v-if' ? Into element? – Alexey Starinsky Nov 09 '18 at 13:08
  • exactly. tell me if its working... – Efrat Levitan Nov 09 '18 at 13:13
  • not sure its router-link. maybe router-view – Efrat Levitan Nov 09 '18 at 13:16

1 Answers1

2

First thing first: The approach you are thinking of (reloading the entire page) just to reset your app to the initial state and redirect the user to the Login page is WRONG.

You have multiple alternatives to handle your problem (token expiry/unauthorized access to your app)

  1. Implement a refresh token functionality, so whenever you face situations of token expiry you refresh user token internally without the user having to worry or even know about it, or
  2. if the token is not refreshable (or you don't want such functionality) then just clear out user's info from wherever you are saving it (Localstorage or only in the vuex store) and redirects the user using router.push() back to Login page.
  3. expanding on @LinusBrog answer in this post you can also extract the initial data outside the original state in a function, and then use that same function for first time initialization of your state and then later, in token expiry case when you want to reset it, and then again redirecting the user to your Login route using router.push() method.

In both (2) and (3) you would also need to implement route guards which, in the absence of a token, will not allow the user to go inside your application, and will always redirect him back to login.

an example route guard could be:

routes: [
  {
    path: '/login',
    name: 'Login',
    beforeEnter: guardRoute,
    component: Login
  },
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: Dashboard,
    beforeEnter: guardUserRoute,
  }
]

function guardAdminRoute (to, from, next) {
  // get your token here either from localstorage or Vuex store

  if (!auth.token) {
    next({
      name: 'Login',
      query: { redirect: to.fullPath }
    })
  } else {
   next()
  }
}

Now, for the cancelation of all your Axios requests, Axios support cancellation of requests since v0.15. here is a nice documentation for it.

And yes, answering your edited question, as a quick ugly hack, you can use window.location.reload() function to reload your app but then again you would need to redirect the user to the Login route.

waleed ali
  • 1,175
  • 10
  • 23