How to deal with session timeout (or expired token), when there is no routing on link in angular 4

Viewed 9797

I have one very common scenario for the expired token as below, Kindle assists me in how to deal with this.

my application session is 30 min, now let's say, I am on one a page longer than 30 min then clicking any other page link. so it will redirect to login page. here, redirect through routing so active guard comes in the picture and check if the token is expired then redirect to a login page. so far it looks good. it is working fine.

however, lets say , I have a refresh link(which refreshing table record by calling new get http request) on the same page which just refresh table records (it is not refreshing whole page). if I am on the same page more then 30 min , and click on refresh button, how to check token is expired or not. since, in this refresh scenario routing is not being used so it won't go to active guard to check token is expired or not.

Could you please guide me on how to deal with this use case.

Thanks in advance !!!

2 Answers

enter image description here

In our environment, to provide the best UX possible, users are not redirected to the login page on session expiry.

Instead, the entire page is blurred and a modal is shown that requires a password input and contains a submit button as above.

Main advantages of this approach are:

  1. Avoiding frustration for losing unsaved work during redirects.
  2. A more seemless re-authentication experience.

Similar to some of the answers described here - https://ux.stackexchange.com/questions/7195/best-practices-for-warning-of-session-expiration

How to achieve this in Angular?

  1. On a successful 1st login, write the date/time that the session will expire into localStorage e.g new Date() + 30 minutes.
  2. Inject e.g authentication.service.ts at the app level, which will have a setInterval(() => checkSessionTimeout(), e.g every 1 minute) inside its constructor. This approach will ensure that this method will run on new tabs / windows as well.
  3. Create a method checkSessionTimeout() that outputs how many minutes remaining until session timeout and write it into a variable in authentication.service.ts e.g sessionTimeoutIn: number;
  4. Create a component that will contain the re-authenticate modal as shown in the image above. Inject this component at the app level with <app-re-authenticate-modal *ngIf="authenticationService.sessionTimeoutIn <= 0"></app-re-authenticate-modal>
  5. For the blurring effect, add a class to your body / main with [class.blur]="authenticationService.sessionTimeoutIn <= 0"
  6. For even better experience, create a div that pushes the main / body, and enters the view from the top that contains this, which can be controlled with <div *ngIf="authenticationService.sessionTimeoutIn > 0 && authenticationService.sessionTimeoutIn <= 2"></div>:

enter image description here

After these, the user should not be able to attempt to do anything other than re-authenticating, and you can still use your AuthenticationGuards.

Hope it helps.

Inside your CanActivate route guard you might be returning either a Promise<boolean> or an Observable<boolean> or a boolean.

But inside the same guard file, you might also be relying on a service that returns to you true or false based on whether the token has expired or not. And this is in-turn something that you might be returning from your Guard.

Let's assume that the AuthService is checking whether the Auth Token has expired on not. And the Data Service is getting the data for you.

Now, before you refresh this data, you can again check for the same by injecting this AuthService in your DataService as a dependency and then checking if the token has expired or not.

Alternatively, your API can check whether this request was authenticated or not. To do that, it would require you to send an Authorization Header with every request. In such a scenario, you can employ an HttpInterceptor. This interceptor will intercept every outgoing request to check whether it has an Authorization header present on it. If present, only then it will allow the request to proceed. If not, you can do the needful by navigating the user back to the login page.

Related