Session timeout using prototype

Dear all

I want my rails web application include a timeout function using
prototype…

say, if the browser is idle for 15 mins, then it automatically redirect
to the admin/logout, where admin is my controller name, logout is the
method name.

I have google around and could not find the solution… Sorry for this
easy question, but I have really no idea of it.

Please hint me on this…million thanks.

Many thanks
Valentino

On Tue, Jun 23, 2009 at 11:28 AM, Valentino
Lun[email protected] wrote:

I have google around and could not find the solution… Sorry for this
easy question, but I have really no idea of it.

Please hint me on this…million thanks.

Many thanks
Valentino

You can use setTimeout to execute a function after a period,

Andrew T.
http://ramblingsonrails.com

http://MyMvelope.com - The SIMPLE way to manage your savings

Thanks for your reply

I think this is not work in my case
My page uses form_remote_tag to search the result, so it display the
result without reloading the whole page…The setTimeout function will
not reset the timer if I use form_remote_tag for searching…

Any idea?

Many thanks
Valenino

Andrew T. wrote:

You can use setTimeout to execute a function after a period,

Andrew T.
http://ramblingsonrails.com

http://MyMvelope.com - The SIMPLE way to manage your savings

On Tue, Jun 23, 2009 at 12:52 PM, Valentino
Lun[email protected] wrote:

Many thanks
Valenino

You could have a timeout variable that you set to 15 minutes in the
future
When you update the results, you can also update the variable with a
new timeout time.
Run setTimeout (maybe 1 minute) to check if the time has exceeded the
variable
If it has, change the page, if not, reset the timeout to check again

Andrew T.
http://ramblingsonrails.com

http://MyMvelope.com - The SIMPLE way to manage your savings

“say, if the browser is idle for 15 mins, then it automatically redirect
to the admin/logout, where admin is my controller name, logout is the
method name.”

To get it to only log them off if the browser has been idle for 15
minutes you could create a javascript listener. The easiest way would be
to detect mouse movement, key presses, clicks and supplement that with
an onunload listener so all bases are covered. When time runs out, the
page is automatically redirected and the session reset. When the page
unloads, the server is notified. The server will then store an attribute
in their session specifying when they became inactive. Depending on
whether or not you are using the cookie session store, you might want to
store this info in the database rather than in the session store just
because there is a remote possibility of a replay attack. If the user
reloads any page more than 15 minutes after the last activity, the
session will reset.

Here is the code (it assumes you are using prototype):

// idle.js
// portions adapted from
http://www.andrewsellick.com/67/simple-javascript-idle-state-using-//prototype
// 15 min in ms
var idleTime = 900000;
var timeOut = ”;

function init() {
new Ajax.Request(‘/login/inactivity?action=check’,
{asynchronous:true, evalScripts:true});
Event.observe(document.body, ‘mousemove’, resetIdle, true);
Event.observe(document.body, ‘click’, resetIdle, true);
Event.observe(document.body, ‘keypress’, resetIdle, true);

setIdle();

}

function onIdleFunction(){

new Ajax.Request('/login/logout?rsn=inactivity', {asynchronous:true, 

onComplete:function(){document.location.href=‘/login’}});

}

function resetIdle(){

window.clearTimeout( timeOut );
setIdle();

}

function setIdle(){

timeOut = window.setTimeout( "onIdleFunction()", idleTime );

}
function unloadReport() {
new Ajax.Request(‘/login/inactivity?action=set’, {asynchronous:true});
}
Event.observe(window, ‘load’, init, false);
Event.observe(window, ‘unload’, unloadReport, false);

Controller code will follow in the next post

Ben V. wrote:

// idle.js
// Adapted from
//
http://www.andrewsellick.com/67/simple-javascript-idle-state-using-//prototype
// 15 min in ms
var idleTime = 900000;
var timeOut = ”;

function init() {
new Ajax.Request(‘/login/inactivity?do=check’,
{asynchronous:true, evalScripts:true});
Event.observe(document.body, ‘mousemove’, resetIdle, true);
Event.observe(document.body, ‘click’, resetIdle, true);
Event.observe(document.body, ‘keypress’, resetIdle, true);

 setIdle();

}

function onIdleFunction(){

 new Ajax.Request('/login/logout?rsn=inactivity', 

{asynchronous:true,
onComplete:function(){document.location.href=‘/login’}});

}

function resetIdle(){

 window.clearTimeout( timeOut );
 setIdle();

}

function setIdle(){

 timeOut = window.setTimeout( "onIdleFunction()", idleTime );

}
function unloadReport() {
new Ajax.Request(‘/login/inactivity?do=set’, {asynchronous:true});
}
Event.observe(window, ‘load’, init, false);
Event.observe(window, ‘unload’, unloadReport, false);

EDIT: use this updated version of the code

Goes in login controller

def inactivity
case params[:do]
when “check”
# already done by check_activity before filter
when “set”
session[:inactive_at] = Time.now
end
end

application-wide before_filter

def check_activity
if session[:inactive_at]
if session[:inactive_at] < 15.minutes.ago
reset_session
flash[:notice] = “Your session has timed out due to inactivity.”
redirect_to :controller => :login
else
session[:inactive_at] = nil
end
end
end

The reason I use inactive_at rather than last_active is that the
mouse/keyboard/click activity part would use up too many resources if it
continually let the server know when stuff happened.