Do you need to check for inactivity of the user in your Vue apps? If the user is inactive in a period of time, then you wanna to automatically logout the user or show a timer first. Normally, system with confidential data likes bank normally implement this kind of feature.
Goals
To have a Vue apps that listen for inactivity for 3 seconds and show a modal with a 10 second timer. If there is no action during the 10 seconds session, automatically logout the user.
Requirement
- Vue
- Vuex
- Idle-Vue
Instructions
Assume you have Vue apps running in your local with vex right now. Let’s install the idle-vue
package first by running
npm install idle-vue
Then, let’s add our library into main.js
file. For now, we will set 3 second for idle time. This is for testing purpose. I added store
as a parameter in IdleVue
because we want to access the state of idle. Thanks to this library.
Main.js
import IdleVue from "idle-vue";
const eventsHub = new Vue();
Vue.use(IdleVue, {
eventEmitter: eventsHub,
store,
idleTime: 3000 // 3 seconds,
startAtIdle: false
});
This idle-vue
have done a great job dealing with listening to inactive event. We can take advantage for vuex, to get the data of status idle in state management.
Basic
Let’s start with basic functionality. So, in your App.vue
file add a computed
property called IsIdle
that return this.$store.state.idleVue.isIdle
. It’s a state from the idle-vue
package. It will return boolean
data.
If you’re not defined store
in your IdleVue
parameter, the value will be undefined
.
App.vue
<template>
<div id="app">
<p>Is it Idle? - {{ isIdle }}</p>
</div>
</template>
<script>
export default {
computed: {
isIdle() {
return this.$store.state.idleVue.isIdle;
},
},
};
</script>
If we didn’t active for 3 seconds, it stated false
If we’re moving cursor or do any activity, it will stated `yes
It shows that Idle-Vue
plugins work well in our Vue apps.
Lets add some modal
Let’s create a design for modal. In this example, I’m using TailwindCSS. I added this modal element in separate component.
/src/components/ModalIdle.vue
ModalIdle.vue
<template>
<div class="overlay">
<div class="modal">
<div class="modal__title">
<span>Session Expired</span>
</div>
<div class="p-3">
<p>You have left this browser idle for 10 minutes.</p>
<p>10 second left</p>
</div>
</div>
</div>
</template>
<style lang="postcss" scoped>
.overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.3);
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
}
.modal {
width: 500px;
box-shadow: 1px 2px 4px rgba(153, 155, 168, 0.12);
border-radius: 4px;
@apply bg-white p-2;
}
.modal__title {
color: #38404f;
@apply flex items-center justify-between p-3 font-bold;
}
</style>
Cool. Let’s import this modal into our App.vue
file and add it into our template. The component will be shown if the isIdle
is true
.
App.vue
<template>
<div id="app">
<ModalIdle v-if="isIdle" />
<router-view />
</div>
</template>
<script>
import ModalIdle from "@/components/ModalIdle;
export default {
components: {
ModalIdle
},
computed: {
isIdle() {
return this.$store.state.idleVue.isIdle;
}
}
};
</script>
Congratulation. Now we have a modal if the user is idle. Next, we’re going to create a timer in the modal.
Timer in the modal
What we’re going to do is to add a 10 seconds window for user to take an action before we’re going to remove the user session or logout.
First of all lets create a time
variable in our ModalIdle.vue
file. This variable will be shown in the modal. We will be used in millisecond format. Let’s add second
in computed
property to display the time in second format.
ModalIdle.vue
<template>
<div class="overlay">
<div class="modal">
<div class="modal__title">
<span>Session Expired</span>
</div>
<div class="p-3">
<p>You have left this browser idle for 3 second.</p>
<p>{{ second }} second left</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
time: 10000,
};
},
computed: {
second() {
return this.time / 1000;
},
},
};
</script>
Then, we need to make the time
is ticking in the modal like a timer. For to achieve this kind of approach, we need to use setInterval
to modify the time
variable. Since, we’re using the setInterval
, then we need to use clearInterval
to kill the the timer.
This is how it should looks like in our component.
ModalIdle.vue
<template>
<div class="overlay">
<div class="modal">
<div class="modal__title">
<span>Session Expired</span>
</div>
<div class="p-3">
<p>You have left this browser idle for 10 minutes.</p>
<p>{{ time }} second left</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
time: 10000,
};
},
created() {
let timerId = setInterval(() => {
this.time -= 1000;
if (!this.$store.state.idleVue.isIdle) clearInterval(timerId);
if (this.time < 1) {
clearInterval(timerId);
// Your logout function should be over here
alert("logout user....");
}
}, 1000);
},
};
</script>
Let me explain what’s going on in the component.
We set a setInterval
function to subtract the time
variable by 1000
every 1 second.
let timerId = setInterval(() => {
this.time -= 1000;
...
}, 1000);
If the user is coming back to active state from idle, we need to stop the setInterval
method from running in the background by using clearInterval
method.
let timerId = setInterval(() => {
this.time -= 1000;
if (!this.$store.state.idleVue.isIdle) clearInterval(timerId);
...
}
}, 1000);
If there is no action from user in 10 seconds, we need to kill the interval and redirect the user to sign out the user and redirect to the login page
let timerId = setInterval(() => {
this.time -= 1000;
if (!this.$store.state.idleVue.isIdle) clearInterval(timerId);
if (this.time < 1) {
clearInterval(timerId);
// Your logout function should be over here
alert("logout user....");
}
}, 1000);
Source Code
App.vue
<template>
<div class="max-w-2xl mx-auto py-16">
<p>Is it Idle? - <span class="font-bold">{{isIdle}}</span></p>
<ModalIdle v-if="isIdle"/>
</div>
</template>
<script>
import ModalIdle from "@/components/ModalIdle;
export default {
components: {
ModalIdle
},
computed: {
isIdle() {
return this.$store.state.idleVue.isIdle;
}
}
};
</script>
ModalIdle.vue
<template>
<div
class="overlay"
>
<div class="modal">
<div class="modal__title">
<span>Session Expired</span>
</div>
<div class="p-3">
<p>You have left this browser idle for 10 minutes.</p>
<p>{{ time }} second left</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
time: 10000
}
},
created() {
let timerId = setInterval(() => {
this.time -= 1000;
if (!this.$store.state.idleVue.isIdle) clearInterval(timerId);
if (this.time < 1) {
clearInterval(timerId);
// Your logout function should be over here
alert('logout user....');
}
}, 1000);
}
};
</script>
You can view the source code in my github - Source Code
Thanks for reading my article. Let me know if you have any idea, what should I write on my next article.