Skip to main content
February 23, 2010
Question

how to make ColdFusion pages time out

  • February 23, 2010
  • 3 replies
  • 3313 views

We use ColdFusion 8 with sql server 2008 in the background. I've been asked to make the cfm pages in 4 frames "time out" for security

The idea I have now is to have application.cfm create a cookie if it's not there already (setclientcookies is no in the cfapplication tag) and write a 0 to it. A Javascript in one of the other cfms will check to see if the cookie has a sufficiently large value and if yes, parent.locate etc to an empty cfm in 3 frames and put a login one in the 4th frame. Anytime a user moves to a new page, the cookie value goes back to 0 and checking starts over.

Is there an easier way to do this ?

    This topic has been closed for replies.

    3 replies

    February 24, 2010

    Original idea seems to work but writing counter to cookie with Javascript didn't update value using ColdFusion, so updated with js on each submit intead.

    February 28, 2010

    the code below is a pile of crap but it should give you an idea as to a former co-worker went about forcing a user out with JS...   It used to play a warning sound but thats been crippled.  Its missing the supporting markup but should suffice as an example to anyone with some experience, and as an example of how not to code a routine :-)

    Place code into a file called timeout.cfm.

    then call it like this :

    <CF_Timeout WarningThreshold="2" TimeOutMinutes="20">

    <CFPARAM Name="Attributes.TimeOutMinutes" Default="30">

    <CFPARAM Name="Attributes.WarningThreshold" Default="2">

    <CFPARAM Name="Attributes.WarningMessage"

    Default="<span style=\'color:red; background-color:white;\'>Timeout in #Attributes.WarningThreshold# minute(s).</span><button class=\'LogoutReset\' onclick=\'ResetSession()\'>Reset</button>">

    <CFPARAM Name="Attributes.WarningNoiseMessageBegin"

    Default="<span style=\'color:red; background-color:white;\'>Timeout in">

    <CFPARAM Name="Attributes.WarningNoiseMessageEnd"

    Default="</span><button class=\'LogoutReset\' onclick=\'ResetSession()\'>Reset</button>">

    <style type="text/css">

    .LogoutReset {

    border:1px solid black ;

    padding:0;

    margin:0;

    height:16px;

    font-size:10px;

    background-color:#8D8;

    vertical-align:top;

    }

    </style>

    <CFOUTPUT>

    <SCRIPT type="text/javascript">

    // Global variables

    StartTime = new Date();

    StartMils = Date.parse(StartTime.toLocaleString());

    TimeOutMils = StartMils + (60000 * #Attributes.TimeOutMinutes#);

    ThresholdMils = 60000 * #Attributes.WarningThreshold#;

    var userReset = false;

    var resetSessionPrepared = false;

    var WarningNoise = false;

    var timerLoop;

    function ResetSession() {

    userReset = true;

    StartTime = new Date();

    StartMils = Date.parse(StartTime.toLocaleString());

    TimeOutMils = StartMils + (60000 * #Attributes.TimeOutMinutes#);

    ThresholdMils = 60000 * #Attributes.WarningThreshold#;

    try{document.getElementById('TimerLocation').innerHTML = 'Session Reset'} catch(e){}

    clearInterval(WarningNoise)

    CountDown()

    }

    function PlayWarningNoise() {

    try{

    mCurrentTime = new Date();

    mCurrentMils = Date.parse(mCurrentTime.toLocaleString());

    mRemainingMils = 10 + Math.ceil((TimeOutMils - mCurrentMils) /1000) ;

    if (mRemainingMils < 1) window.location.href="controller.cfm?action=logout"

    document.getElementById('TimerLocation').innerHTML = '#Attributes.WarningNoiseMessageBegin# ' + mRemainingMils + ' seconds.#Attributes.WarningNoiseMessageEnd#'

    //EvalSound("sound1")

    } catch(e){}

    }

    function CountDown()

    {

    if (timerLoop) clearTimeout(timerLoop);

    CurrentTime = new Date();

    CurrentMils = Date.parse(CurrentTime.toLocaleString());

    RemainingMils = TimeOutMils - CurrentMils;

    //window.status = 'timer:' + TimeOutMils  + ' : ' + CurrentMils

    if(RemainingMils < ThresholdMils){

    try{document.getElementById('TimerLocation').innerHTML = '#Attributes.WarningMessage#'} catch(e){}

    if (resetSessionPrepared != true)  {

    //try{ EvalSound("sound1") } catch(e){}

    WarningNoise = setInterval( 'PlayWarningNoise()', 5000)

    setTimeout( 'if (userReset==false) {window.location.href="controller.cfm?action=logout"} else {userReset=false;}',ThresholdMils )

    }

    resetSessionPrepared = true;

    }

    else

    {

    timerLoop = setTimeout('CountDown()', 10000);

    resetSessionPrepared = false;

    try{document.getElementById('TimerLocation').innerHTML = 'Timeout in ' + Math.ceil(RemainingMils/60000) + ' minutes'} catch(e){}

    }

    }

    // run CountDown for the first time

    CountDown();

    //function EvalSound(soundobj) {

    // try{

    //var thissound=document.getElementById(soundobj);

    //thissound.Play();

    // }

    // catch(e){}

    //}

    </SCRIPT>

    </CFOUTPUT>

    Inspiring
    February 23, 2010

    How about using a CF component/webservice for controlling user time-out and connecting it using AJAX from your frames.  Something like this:

    1) Client frames are loaded

    2) On each frame:

         a) AJAX call to web service to log activity date/time (used to determine most recent page access time)

         b) JS timer on the frame performs AJAX call to Web service after X minutes to determine if client has exceeded time out

         c) if so, browser is relocated to time out page

         d) if not, reset the timer and try again in X minutes from last access time

    I'm sure there is a more elegant solution out there (probably only putting this code in 1 frame is a good start).  Of course, you would have to couple a solution like this with a server-side solution as well (e.g. CF Server application time-out setting).

    BKBK
    Community Expert
    February 23, 2010

    Is there an easier way to do this ?

    Good question. You lost me after a few seconds.

    Do you mean, time the page out if it fails to respond, or time it out anyway after a given period? The first alternative is usually the case.

    If so, you could just do the obvious. One standard way to set a timeout on CFM pages is, for example

    <cfsetting requestTimeout="60"><!--- time page out if it is unreponsive after 60 seconds --->

    February 23, 2010

    BKBK,

    They want me to make them timeout and disappear after 30 minutes if there is no one does anything on them.

    Sorry for my explanation being too wordy. Trying to have a JavaScript counter write an increasing count to a cookie every so often and if a user submits to a new cfm, application.cfm will reset the cookie to 0. If the val in the cookie hits a certain amount, want to parent.locate etc to 3 cfms to 3 frames that display nothing and a login screen in the remaining frame.

    Tried cfsetting tag and after the requesttimeout but saw no effect.

    February 25, 2010

    If you want the client interface to time out you need to use a client technology like JavaScript.

    If you want the server state to time out you need to use server technology like ColdFusion's session time out.

    If you want both to time out, you need to use both technologies, timed to about the same time.  Just realize this is not an exact science and one side can time out at a different second than the other depending on many factors.  But for 99.873% of the cases I'm aware of, this is good enough.

    JavaScript Timing Events

    http://www.w3schools.com/js/js_timing.asp

    P.S.

    This is the only way to do it with normal HTTP communications, becasue a server can not push new content to a client.  In normal HTTP comunications the client only pulls new information from the server when the client makes a new request.

    If you want to go to a solution like FLEX that uses a flash client and flash remoting, the server can push data to the client.  But that is not a simple, one forum post solution.


    Ian Skinner,

    Thanks. The session timeout works in real and the client side works in test. I will keep them timed the same and hope for the best.

    Could data get from server to client with unseen request-maybe invisible frame (no border, framespacing,scroller) with cfm in it that has Javascript timer that submits that cfm periodically and returns server time or if a session var is still defined?