How to implement a session expiration reminder with JavaScript? - javascript

I really want to prompt my user to keep the session alive, shortly before it expires.
Yesterday, I asked the question "How can I check if the session is dead, then prompt an alert?" and somebody answered with an AJAX/JSON solution, that made calls every 30 seconds to an ASP page. This didn't work, as the calls to the server kept the session alive - so it would never log out.
I kept reading and came across a similar [SO] question, where somebody suggested using a JS countdown that prompted the user to renew the session, 5 minutes before the session is due to expire.
This is what I have done so far but:
The function startMainTimer does not seem to be keeping the time because I did not receive an alert when the timer was due to alert.
The $('body').mousedown() feature doesn't work as it should. It works but if a user clicks a link, the mousedown function works but doesn't follow the link after the function has run.
Here’s the code:
<script>
$(document).ready(function() {
$.ajax({ // get session expiration value e.g. 60
type : 'GET',
url : '../getSessionValue.asp',
dataType : 'text',
success : function(data) {
if (data != '') {
var newSessionValue = data - 5
startMainTimer(newSessionValue * 60000); // deduct 5 minutes, convert to mSeconds & call startNewTimer()
}
}
});
$('body').mousedown( function() { // if user clicks anywhere on page call ajaxRenewSession() function
ajaxRenewSession();
});
$('#userButtonRenewSession').click( function() { // if user clicks continue browsing button
ajaxRenewSession();
});
});
function startMainTimer(newSessionValue,restart) {
if (restart == 'yes') {
clearInterval(interval);
}
var counter = 0;
var interval = setInterval(function() {
counter++;
if (counter == newSessionValue) {
alert("Your session is about to expire!");
clearInterval(interval);
}
}, 1000);
}
function ajaxRenewSession() { // AJAX the server to renew session, get session timeout value and then reset JS timer
$.ajax({
type : 'GET',
url : '../renewSession.asp',
dataType : 'text',
success : function(data) {
if (data != '') {
var newSessionValue = data - 5
startMainTimer(newSessionValue * 60000, 'yes');
}
}
});
}
</script>
Can anybody help me rectify these problems?

The thing with mouseup seems to work, I tested it on stackoverflow.com. However, it may not work in some cases, e.g. if the user presses a link, drags it and then drops it. In this case, no event was raised for me.
Another thing: You will have to clear the main timer at the beginning of startMainTimer because otherwise, everytime the user clicks somewhere, an additional timer would be started.
And you know that the last call of startMainTimer misses a parameter?

Related

User should automatically logout after close browser tab not only browser

I am working on PHP and MySql. I need a feature, when user close browser tab, a user should log out automatically.
I have used javascript onbeforeunload event. But it is not working, this event executes for page refresh also.
Here is my sample code,
window.onbeforeunload = function(){
$.ajax({url: "logout.php", success: true});
return 'Are you sure ?';
};
Idea would to poke the backend every 2 seconds and expire the session when you stop for let's say 5 seconds? This way 3 to 5 seconds after closing the tab session would automatically expire.
setInterval( function() {
$.get('/poke.php');
}, 2000);
While php side:
// poke.php
$_SESSION['poke'] = time();
// Probably your index.php
if (isset($_SESSION['poke'] && time() - $_SESSION['poke'] > 5) {
// Do the logout
} else {
$_SESSION['poke'] = time();
}

Knockout setTimeout delay

When a user logs into my website, I store a "logged in until" parameter on my server for that user, which is updated each time they interact with the server. So if they are inactive for X seconds, they should be logged out and the page on their client refreshed to show the login screen. Everything works nicely except the function keeps calling itself at 1 second intervals, and not the 1700+ second interval I'm looking for. As each call hits the server, I don't want this to keep running more often than it needs to.
This function is contained within my knockout viewmodel. logoutTimer is declared as a global variable. Watching the console log I can see the delay shows the correct time, but it seems to be running about every 1 second.
self.autoLoginCheck = function() {
clearTimeout(logoutTimer);
//If not, refresh the main screen => that'll push them to the login screen automatically
myurl = "/api/checkLoginStatus.php";
var parameters = {
'userPublicID':self.userInfo().userPublicID
}
$.post(myurl, parameters, function(data) {
var getResponse = JSON.parse(data);
if (getResponse.loggedIn < 1 ) {
//This is the log out condition
location.reload(true);
} else {
//Check how many more seconds the current log in is good for, that's when we'll check it again
var msdelay = getResponse.nextCheck * 1000;
console.log("Delay is " + msdelay);
logoutTimer = setTimeout(self.autoLoginCheck(), msdelay);
}
});
}
I know this type of question has been asked many times, but reading all those answers I can't see why this function is running every second and not waiting 30 minutes. Thanks to whoever shows me the obvious!
The first parameter to setTimeout should be a function, not the result of a function.
logoutTimer = setTimeout(self.autoLoginCheck, msdelay);

Capture user Idling using javascript

Our site has ifame links to different content sites which are used to do online exams
Some exams in the content pages are running 3+ hours
Also exam guard is there for prevent the users doing other stuff while doing the exams
The problem is that once user completed the exams over 3+hrs and come to the parent site (our site)
It has session time out issue in parent page, (Parent site session time out is set to 180min )
As a solution for this we have implemented following JQuery
var to;
$(document).ready(function () {
to = setTimeout("TimeOut()", 10000);
});
function TimeOut() {
$.ajax({ type: "POST",
url: "KeepAliveDummy.aspx", success: function () {
to = setTimeout("TimeOut()", 10000);
}
});
};
Now the problem is that if one user open Parent site and go away it will keep the session unwantedly,
Any suggestion for capture the idle time?
We can use "mousemove" event and see whether the user is active or not.
I have used the below code to test whether the user idle time reached the Maximum Idle time.
function checkIdleTimeOut() {
userIdleTime++;
if( userIdleTime >= maxIdleTime ) {
alert("Reached max User Idle Time");
clearInterval(intvl);
}
$("#output").html( "userIdleTime: " + userIdleTime );
}
I have provided a sample demo, where the max idle time is set to 5 seconds.
Demo at JSFiddle Demo

Is it possible to know how long a user has spent on a page?

Say I've a browser extension which runs JS pages the user visits.
Is there an "outLoad" event or something of the like to start counting and see how long the user has spent on a page?
I am assuming that your user opens a tab, browses some webpage, then goes to another webpage, comes back to the first tab etc. You want to calculate exact time spent by the user. Also note that a user might open a webpage and keep it running but just go away. Come back an hour later and then once again access the page. You would not want to count the time that he is away from computer as time spent on the webpage. For this, following code does a docus check every 5 minutes. Thus, your actual time might be off by 5 minutes granularity but you can adjust the interval to check focus as per your needs. Also note that a user might just stare at a video for more than 5 minutes in which case the following code will not count that. You would have to run intelligent code that checks if there is a flash running or something.
Here is what I do in the content script (using jQuery):
$(window).on('unload', window_unfocused);
$(window).on("focus", window_focused);
$(window).on("blur", window_unfocused);
setInterval(focus_check, 300 * 1000);
var start_focus_time = undefined;
var last_user_interaction = undefined;
function focus_check() {
if (start_focus_time != undefined) {
var curr_time = new Date();
//Lets just put it for 4.5 minutes
if((curr_time.getTime() - last_user_interaction.getTime()) > (270 * 1000)) {
//No interaction in this tab for last 5 minutes. Probably idle.
window_unfocused();
}
}
}
function window_focused(eo) {
last_user_interaction = new Date();
if (start_focus_time == undefined) {
start_focus_time = new Date();
}
}
function window_unfocused(eo) {
if (start_focus_time != undefined) {
var stop_focus_time = new Date();
var total_focus_time = stop_focus_time.getTime() - start_focus_time.getTime();
start_focus_time = undefined;
var message = {};
message.type = "time_spent";
message.domain = document.domain;
message.time_spent = total_focus_time;
chrome.extension.sendMessage("", message);
}
}
onbeforeunload should fit your request. It fires right before page resources are being unloaded (page closed).
<script type="text/javascript">
function send_data(){
$.ajax({
url:'something.php',
type:'POST',
data:{data to send},
success:function(data){
//get your time in response here
}
});
}
//insert this data in your data base and notice your timestamp
window.onload=function(){ send_data(); }
window.onbeforeunload=function(){ send_data(); }
</script>
Now calculate the difference in your time.you will get the time spent by user on a page.
For those interested, I've put some work into a small JavaScript library that times how long a user interacts with a web page. It has the added benefit of more accurately (not perfectly, though) tracking how long a user is actually interacting with the page. It ignore times that a user switches to different tabs, goes idle, minimizes the browser, etc.
Edit: I have updated the example to include the current API usage.
http://timemejs.com
An example of its usage:
Include in your page:
<script src="http://timemejs.com/timeme.min.js"></script>
<script type="text/javascript">
TimeMe.initialize({
currentPageName: "home-page", // page name
idleTimeoutInSeconds: 15 // time before user considered idle
});
</script>
If you want to report the times yourself to your backend:
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);
TimeMe.js also supports sending timing data via websockets, so you don't have to try to force a full http request into the document.onbeforeunload event.
The start_time is when the user first request the page and you get the end_time by firing an ajax notification to the server just before the user quits the page :
window.onbeforeunload = function () {
// Ajax request to record the page leaving event.
$.ajax({
url: "im_leaving.aspx", cache: false
});
};
also you have to keep the user session alive for users who stays long time on the same page (keep_alive.aspxcan be an empty page) :
var iconn = self.setInterval(
function () {
$.ajax({
url: "keep_alive.aspx", cache: false });
}
,300000
);
then, you can additionally get the time spent on the site, by checking (each time the user leaves a page) if he's navigating to an external page/domain.
Revisiting this question, I know this wouldn't be much help in a Chrome Ext env, but you could just open a websock that does nothing but ping every 1 second and then when the user quits, you know to a precision of 1 second how long they've spent on the site as the connection will die which you can escape however you want.
Try out active-timeout.js. It uses the Visibility API to check when the user has switched to another tab or has minimized the browser window.
With it, you can set up a counter that runs until a predicate function returns a falsy value:
ActiveTimeout.count(function (time) {
// `time` holds the active time passed up to this point.
return true; // runs indefinitely
});

Session time out using Javascript or jQuery

How can I redirect to the login page when the session has completed? The code should check that the user sits idle for some time and then does any other client side event. If it finds this condition, it should check the session time out, and if session completes, redirect to login page.
Checking for inactivity on a webpage will be like an attempt to listen multitude of event. This also means that if there is user interaction the a function (event handler) is going to be called quite a lot of times. If this handler/function is going to some ajax send/receive stuffs then it could ultimately make your user interface perform poorly.
Why not make the session expiration period short and auto log out the user after? That way if the user is truly active then most probably there will a request for a page within that time frame. You could also set up a timer based event which when fired will simply send dummy request to server to refresh the session as a way of letting the server know that the user is still active but just not ready to request another page yet. This would be the case where a user is editing a long text or something like that.
I hope it helps.
Session Logout after 5 minutes
<sctipt>
var interval;
$(document).on('mousemove', function () {
clearInterval(interval);
var coutdown = 5 * 60, $timer = $('.timer'); // After 6 minutes session expired (mouse button click code)
$timer.text(coutdown);
interval = setInterval(function () {
$timer.text(--coutdown);
if (coutdown === 0) {
alert("Session expired User successfully logout.");
window.location = "UserLogin.aspx";
}
}, 1000);
}).mousemove();
var interval;
$(document).on('keydown', function () {
clearInterval(interval);
var coutdown = 7 * 60, $timer = $('.timer'); // After 6 minutes session expired (keyboard button press code)
$timer.text(coutdown);
interval = setInterval(function () {
$timer.text(--coutdown);
if (coutdown === 0) {
alert("Session expired User successfully logout.");
window.location = "UserLogin.aspx";
}
}, 1000);
}).mousemove();
<sctipt>
<div class="timer">
Time of session display on page
</div>

Categories

Resources