OnSelectedIndexChanged and AutoPostBack - javascript

I found some javascript code on here that will display a session timeout warning and a message to inform the user that they have been logged out (as shown below) However my issue with this code is that if the user is not in front of the computer to click the ok button on either one of the alerts no further action is taken. So at the moment the timeout warning is set to be displayed 1 minute before the redirect, when that warning pops up the timer is halted until the user clicks the button and the second message pops up 1 minute after the user clicks the ok button then the redirect doesn't happen until the user clicks the button on that warning. The biggest of the issues here for me is that obviously the actual session timer is completely separate to these javascript timers so if the user is not in front of the screen when the first warning message pops up saying they have a minute before the session expires and that minute passes, then they see the message and click ok, they have not been redirected and will think they have one minute left but the session has already expired and I have code in each page the timer runs on so that they redirect to the index page if the timer has expired and all of the session variables stored are gone so they click on something and will be redirected anyway.
Is there a better way to do this? Can I use the javascript to poll the session state and find out how much time is actually remaining rather than running a completely separated timer?
<script type="text/javascript">
var iddleTimeoutWarning = null;
var iddleTimeout = null;
function pageLoad() {
if (iddleTimeoutWarning != null)
clearTimeout(iddleTimeoutWarning);
if (iddleTimeout != null)
clearTimeout(iddleTimeout);
var millisecTimeOutWarning = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeoutWarning"]) * 60 * 1000 %>;
var millisecTimeOut = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeout"]) * 60 * 1000 %>;
iddleTimeoutWarning = setTimeout("DisplayIddleWarning()", millisecTimeOutWarning);
iddleTimeout = setTimeout("TimeoutPage()", millisecTimeOut);
}
function DisplayIddleWarning() {
alert("Your session will expire in one minute due to inactivity.");
}
function TimeoutPage() {
alert("Your session has expired due to inactivity.");
location.replace("index.aspx");
}
</script>
Thanks.

alert blocks the UI and any further script execution.
So just use some other form of dialog, f.e. the ones that jQuery UI provides.

Related

stop Chrome from restoring the session

Is there any way to tell chrome to NOT restore the session when re-opening a closed page? Maybe a special header?
When my employees log into my company app it is very state dependant. If they are inactive for 60 minutes I want to log them out and delete all data relevant to what they were doing, but the problem is that Chome has this handy feature where it will re-open your page right where you left off and not question a thing. My website will not know that they had the browser closed for two days and the setTimeout will not fire for another 50 minutes.
I have another couple of wacky workarounds, but I would prefer it if I could just tell Chrome to not try salvaging old sessions and instead treat every opening like it was just opened for the first time. maybe a disable caching through javascript?
Edit:
I am using IIS to serve the Angular 9 static html and javascript.
So, as you mentioned, you're using a static website without a backend. Though you haven't mentioned anything, I'm assuming you're using sessionStorage or localStorage to handle authentication. If that's the case, what you can do is set a timer whenever a user logs in and maintain a localStorage to keep track of the idle time.
let obj_date = new Date();
let miliseconds = obj_date.getTime(); // Returns the number of miliseconds since 1970/01/01
localStorage.setItem("idle_time",miliseconds);
After that, keep calling the following function from within something like setInterval() every 10,20,30 or 60 seconds (as per your choice) to check if that time limit has expired.
function check_if_session_expired() {
let max_idle_minutes=60;
let miliseconds_now = obj_date.getTime();
let get_idle_time_in_miliseconds = localStorage.getItem("idle_time");
let one_minute_to_milisecond = 1000 * 60;
if ((Math.round(miliseconds_now / one_minute_to_milisecond) - Math.round(get_idle_time_in_miliseconds / one_minute_to_milisecond)) >= max_idle_minutes) {
console.log("expired");
//logout the user and clear sessionStorage/localStorage if you want
} else {
localStorage.setItem("idle_time",miliseconds_now);
}
}
You can use cookies to so the same.
What you want to do is destroy session from server side. Check the code below which is written in php. However, if you get the idea, you can use anything to implement it.
<?php
session_start();
//Expire the session if user is inactive for 60 minutes or more.
$expireAfter = 60;
//Assign the current timestamp as the user's latest activity
$_SESSION['last_action'] = time();
//Check to see if our "last action" session variable has been set.
if(isset($_SESSION['last_action'])){
//Figure out how many seconds have passed since the user was last active.
$secondsInactive = time() - $_SESSION['last_action'];
//Convert our minutes into seconds.
$expireAfterSeconds = $expireAfter * 60;
//Check to see if they have been inactive for too long.
if($secondsInactive >= $expireAfterSeconds){
//User has been inactive for too long. Kill their session.
session_destroy();
unset($_SESSION);
header("Location: http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']."/example/login.php");
exit;
}
}
This is just a simple implementation and you can definitely extend it to make it work the way you want.

Dealing with session along multiple tabs

Recently came across this problem. The scenario is, let's say I have two tabs open (A and B), I login with Tab A authenticates redirects to the home page. Then selected a link instead of just entering, I right click and pick "Open link in a new tab" thus having Tab B. At this point I start navigating for 30 mins a alert pop up saying my "Session has been finish. Please login again.". Instead of being redirected to the Login page I was redirected to the home page. (The alert must be coming for Tab A)
If I was dealing with only one Tab this isn't an Issue after the alert I would go directly to the Login Page.
I have two set of codes one handles the actual session expiration and the other gives out the alert.
This code is for the alert:
function idleLogout() {
var t;
window.onload = resetTimer;
window.onmousemove = resetTimer;
window.onmousedown = resetTimer;
window.onclick = resetTimer;
window.onscroll = resetTimer;
window.onkeypress = resetTimer;
function logout() {
alert("Session has been finish. Please login again.");
window.location.href = '{{url("")}}';
}
function resetTimer() {
clearTimeout(t);
t = setTimeout(logout, {{ env('SESSION_LIFETIME')*60*1000 }} );
}
}
idleLogout();
Code is working as intended but it can be implemented better.
Btw, if it matters using PHP Laravel 5
The problem is that you're using JavaScript to handle your timeouts. JavaScript (by default) is only confined to a single tab. While you could make use of COOKIES in JavaScript to communicate between tabs, it would make far more sense to handle session timeouts through server-side SESSION variables, which persist across tabs.
A thirty minute forced timeout can be achieved in PHP, courtesy of this answer:
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
Hope this helps.

Control duration of the session PHP

I am very beginner in web development. I spent some time realizing the way to limit session time in PHP. I have read Stackoverflow suggestions but none of them seems to work for me (cookies-might be edited by user, AJAX communication-extra load on server and static PHP - what about passive tabs in browser? Validation using session vars).
I have in mind this:
<script type="text/javascript">
$(document).ready(function() {
setTimeout(function() {
window.location.href = 'logout.php';
}, 10000);
});
</script>
...to limit session time for users. This system will be used in a management web app. Could anyone point out potential drawbacks of my approach, because it seems to be too simple to be good?
<?php
function check_user_is_valid () {
//Start our session.
session_start();
//Expire the session if user is inactive for 30
//minutes or more.
$expireAfter = 30;
//Check to see if our "last action" session
//variable has been set.
if(isset($_SESSION['last_action'])){
//Figure out how many seconds have passed
//since the user was last active.
$secondsInactive = time()-$_SESSION['last_action'];
//Convert our minutes into seconds.
$expireAfterSeconds = $expireAfter * 60;
//Check to see if they have been inactive for too long.
if($secondsInactive >= $expireAfterSeconds){
//User has been inactive for too long.
//Kill their session.
session_unset();
session_destroy();
}
}
}
//Assign the current timestamp as the user's
//latest activity
$_SESSION['last_action'] = time();
Call check_user_is_valid () function on every php page to check if the user have valid session.It will automatically destroy session if page is still for 30 minutes.
Update the value of $_SESSION['last_login'] variable with new time on every page, so that the user get 30 minutes session for each and every page.

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