Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

how to make ColdFusion pages time out

Guest
Feb 23, 2010 Feb 23, 2010

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 ?

3.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2010 Feb 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 --->

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 23, 2010 Feb 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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 24, 2010 Feb 24, 2010

lwfg wrote:

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.

You may not have to look too far. Putting the global setting sessiontimeout="#createTimeSpan(0,0,30,0)#" in Application.cfm makes any page to time out if the user does nothing in it within 30 minutes.

Even better, use Application.cfc instead. It has events that can be fired when 30 minutes are exceeded.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 25, 2010 Feb 25, 2010

BKBK,

Tried this in application.cfm a while ago

<cfapplication name="a" clientmanagement="yes" clientstorage="registry" sessionmanagement="yes" sessiontimeout="#createtimespan(0,0,60,0)#">

put this in the 1st regular template that runs

<cflock timeout="60" type="exclusive">
    <cfset session.timeval=q_id.name>
</cflock>

and in the top of each other template put

<cfif not structkeyexists(session,"timeval")>
     <cflocation url="saytimeout.cfm" />
</cfif>

This works ok but a user has to submit a page for it to show things timed out,

Is there a way with session var that times out a screen that's been idle too long without the user doing anything?

------------------------------------------------------------------------------------------------------------------------------------------------------------------

JavaScript technique seems to work in tests.

Will read about appication.cfc, sounds better.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 25, 2010 Feb 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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 25, 2010 Feb 25, 2010

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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 25, 2010 Feb 25, 2010

Well sort of... It is pretty easy to use JavaScript to cause the client to submit new requess to the server so that the client can pull down new content.

You can do this in the main window.

You can do this in a popup or frame window.

Or you can do it behind the sceens with the XMLHttpRequest object, aka AJAX.

The XMLHttpRequest Object

http://www.w3schools.com/XML/xml_http.asp

But it is important to always remember these are all just fancy ways to have the client pull data from the server.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 27, 2010 Feb 27, 2010

You've found your answer, but here are a few remarks.

lwfg wrote:

Tried this in application.cfm a while ago

<cfapplication name="a" clientmanagement="yes" clientstorage="registry" sessionmanagement="yes" sessiontimeout="#createtimespan(0,0,60,0)#">

You do of course realize it will be sessiontimeout="#createtimespan(0,0,30,0)#" for a 30 minute session timeout. Also, with client management turned on, storing client information in the registry will soon clog it up. I would use

clientstorage="session"

put this in the 1st regular template that runs

<cflock timeout="60" type="exclusive">
    <cfset session.timeval=q_id.name>
</cflock>

There is no need for a lock there.

and in the top of each other template put

<cfif not structkeyexists(session,"timeval")>
     <cflocation url="saytimeout.cfm" />
</cfif>

That is typically the kind of code to put in OnRequestStart. However, be sure to exclude the page saytimeout.cfm itself.

This works ok but a user has to submit a page for it to show things timed out,

Is there a way with session var that times out a screen that's been idle too long without the user doing anything?

There is no way. The client has to connect to the server to be informed of the timeout. As Ian says, what Javascript does is to make this connection.

Will read about appication.cfc, sounds better.

Way to go. Application.cfc automatically fires the events you need, onSessionStart, onRequestStart and onSessionEnd. What's in a name?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 23, 2010 Feb 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).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 24, 2010 Feb 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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 28, 2010 Feb 28, 2010
LATEST

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>

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources