How to Detect User Inactivity in front-end applications.
An overlooked vulnerability in most applications is user inactivity. The concept of what happens to your application when the user that has logged in leaves it unattended in say an open tab and completely forgets about it. This feature though not critical is mostly adopted for finance apps and applications with high risk where even the duration of a vulnerability could be fatal. This countermeasure prevents one of the most basic means of impersonation where an authenticated user leaves the application unattended giving way for unauthorized personnel to use their accounts for malicious purposes in their absence. This is necessary to provide that extra edge in security where your application would instantly log out the user as soon as it detects some inactivity. Before you proceed with this article there are certain things you should be aware of:
- This article covers the implementation of a logout due to inactivity functionality in Vanilla Javascript. The role of converting the techniques used here to any of the javascript frameworks of your choice is up to you.
- This article assumes you have adequate knowledge of Browser Events e.g Mouse Events (https://developer.mozilla.org/en-US/docs/Web/Events).
- This article assumes you have adequate knowledge of some of the functions available in the window object or global scope (in this case timers like setTimeout). https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
THE APPROACH
Before we dive into implementing this functionality, we need to understand how it is going to work. The operation of a logout due to inactivity functionality can be summarized to the following steps:
- Set your interval value e.g 5mins
- Choose a unique event you would use as a yardstick test for inactivity.
- Set a timer to run within the set idle time in step 1.
- Any time your unique event is triggered interrupt the current timer and reset the timer to start afresh.
- Any time the timer completes without interruption perform your defacto logout operation.
The operation starts with coming up with an allowed idle time for your application e.g 5mins, we have to come up with an idle time value to cater for situations where our users might still be active but currently busy on another task we wouldn't want our application to be forcefully logging out users while they are still behind their pcs, So an idle time of 5mins would be generous enough because as a user if you are using an app that requires an active interaction and you’re idle for 5mins that simply means you are doing something else. The next step is choosing a unique event, now this step is mostly by personal preference and it asks what operation would a user make to let the application know that the app is still being used?. For most, it could be click action and in some rare cases, it could be mouse movement actions (Netflix for instance). Feel free to pick the one you like and experiment to see if it works with the user experience of your application but for this article, we are using a more generic operation (clicks). The remaining steps summarize the operation of the logout functionality. This means on-load of the page to be protected start a timer to run within your allowed idle time duration. While the timer is running, whenever any of your operations is activated (in our case whenever a user clicks) reset the timer and whenever the timer runs out (meaning the user did not perform any of our watched operations) we log the user out due to inactivity. Now that we have been able to mind-map the entire flow of the functionality lets see how we can get it to work in code.
THE IMPLEMENTATION
Here we would look at a sample HTML file that would serve as an example of a protected page we would need the logout due to inactivity functionality.
From the HTML file above the implementation is available at the script tags at the bottom of the page. The implementation is really simple as you can see the core of the solution is the eventListener and the setTimeout methods. The flow is on first init the IIFE(Immediately-invoked Function Expression) at line 82 starts by clearing any lingering time hooks by calling the destroyTimeHook function, then it initializes a new time hook to start counting towards the set idle time (1 minute), then the event listeners that would help reset the time hooks anytime they are triggered are registered last and the time hook then calls the actual logout function when the setTimeout is done. Pretty Easy!
I chose to implement this functionality in vanilla javascript to show the most basic implementation that is adaptable to most scenario’s. However, if you are using a front-end framework (e.g Vue or React) there may be a smarter way to do it like in Vue you might want to implement it using the lifecycle hooks, it is just better to show it in vanilla javascript so as to make the solution as generic as possible, feel free to convert it to the frontend framework of your choice. Happy Coding.