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

If user logoff or their session times out how to end coldfusion session?

Community Beginner ,
Mar 06, 2018 Mar 06, 2018

Copy link to clipboard

Copied

I have system that I built and for this project I used Ajax with JQuery. On back end I use ColdFusion and session management to handle users session variables. There is two situations (actually three if we consider closing the browser) where users session will end. One situation is if they click Logoutthen I have function that will clear SESSION scope with all information in it but session is not ended. Also CFID and CFTOKEN are still the same. Here is example of Logout function:

<cffunction name="LogOut" access="remote" output="yes" returnformat="JSON" hint="Used in session timeout handling"> <cfset fnResults = structNew()> <cfset dt = createODBCDateTime(now())>  <cfif structKeyExists(SESSION,"LoggedIn")> <cfset temp = structClear(SESSION)> <cfset fnResults.status = "200"> <cfelse> <cfset fnResults.status = "400"> <cfset fnResults.message = "Error!"> </cfif>  <cfreturn fnResults> </cffunction>

Second scenario is once user session timeout. Here is example of that fucntion:

<cffunction name="timeoutSession" access="remote" output="yes" verifyclient="no" securejson="false"> <cfset temp = structClear(SESSION)> </cffunction> 

Both of these functions will clear the session scope but not end the user session. I have used cfdump to check session scope once user logs out and CFID/CFTOKEN remains the same. I'm wondering how session cna be ended once they hit LogOut or timeoutSession function? Also should I rewrite the CFID and CFTOKEN every time user logs in the system? Here is example of my Application.cfc:

<cfcomponent output="false"> <cfset THIS.name = "MyApplication"> <cfset THIS.sessionManagement = true> <cfset THIS.applicationTimeout = CreateTimeSpan(0, 8, 0, 0)> <cfset THIS.sessionTimeout = CreateTimeSpan(0, 2, 0, 0)> <cfset THIS.requestTimeOut = "60">  <cffunction name="onApplicationStart" access="public" returntype="boolean" output="false"> <cfset APPLICATION.appStarted = now()> <cfset APPLICATION.title = "My Application"> <cfset APPLICATION.functions = CreateObject("component","udfs").init()> <cfset APPLICATION.sessionMinutes = 30> <cfreturn true> </cffunction>  <!--- Runs when your session starts ---> <cffunction  name="OnSessionStart" access="public" returntype="void" output="false"> <!--- Clear the session. ---> <cfset StructClear( SESSION ) /> <!--- Set loggedin flag to false. ---> <cfset SESSION.loggedin = false>  <cfreturn /> </cffunction>  <!--- Run before the request is processed. ---> <cffunction name="onRequestStart" returnType="boolean" output="false"> <cfargument name="thePage" type="string" required="true"> <cfset REQUEST.appCode = 'SPA'> <cfset REQUEST.appName = 'Single Page Application'> <cfset var page = listLast(arguments.thePage,"/")> <!---<cfset onApplicationStart()>---> <cfif !listFindNoCase("Login.cfm,Authentication.cfc",page)> <cfif !structKeyExists(SESSION, "loggedin") OR SESSION.loggedin EQ false> <cflocation url="Login.cfm" addToken="false"> </cfif> </cfif>  <cfreturn true> </cffunction> </cfcomponent>

I'm not sure if session can be ended in Application.cfc or I have to do that in my cffunctions. Same for CFID and CFTOKEN what is the best place to set new values if user logs in again? If aynone have experience with this please let me know. I'm trying to prevent user to use the same session and raise level of security in my SPA. There is one more thing that I found sessionInvalidate() method but they have mentioned that will not invalidate the underlying J2EE session. If I use this method in my LogOut and timeoutSession I can see cfid and cftoken are reset each time. I'm only worried if not ending J2EE session can cause some problems in my app. If anyone can help or provide some feed back on this topic please let me know.

Views

2.9K

Translate

Translate

Report

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 ,
Mar 07, 2018 Mar 07, 2018

Copy link to clipboard

Copied

If user logoff or their session times out how to end coldfusion session?

You shouldn't bother about this. A session timing out is the same thing as a session ending. In any case, this is a task best left to ColdFusion. So you don't need the timeoutSession function.

What you can do is use a sessiontimeout in the usual range, say, 20 to 30 minutes. If the user is inactive in that time, then ColdFusion will time the session out and end it.

What you should be concerned about is login and logout. Remember that, should a user log in and then logout then the session may continue. But that shouldn't bother you. In fact, it shouldn't bother you, if every user were to have a session. After all, you are delivering services to users based on whether or not they are logged in, not based on sessions.

I would suggest that you add the following line to Application.cfc:

<cfset this.loginStorage = "session">

Your logout function should also formally logout the user:

<cffunction name="LogOut" access="remote" output="yes" returnformat="JSON" hint="Used in logging user out">

    <cfset var fnResults = structNew()>

    <cfset fnResults.dt = now()>

  

    <!--- crucial! --->

    <cflogout>

  

    <cfif structKeyExists(SESSION,"LoggedIn")>

        <cfset temp = structClear(SESSION)>

        <cfset fnResults.status = "200">

    <cfelse>

        <cfset fnResults.status = "400">

        <cfset fnResults.message = "Error!">

    </cfif>

    <cfreturn fnResults>

</cffunction>

Votes

Translate

Translate

Report

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 Beginner ,
Mar 07, 2018 Mar 07, 2018

Copy link to clipboard

Copied

First of all thank you for taking time to help with this topic. I use sessionTimeout function once JavaScript function detects timeout is equal to 0. Then sessionTimeout will get triggered. So what you are suggesting is to just clear the session scope and use <cflogout> ? How cflogout will affect the process? Also what about J2EE session? Is there a good way to rotate these session or that is not necessary? Also I'm trying to understand what this line of code is doing <cfset this.loginStorage = "session"> ? Thanks in advance.

Votes

Translate

Translate

Report

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 ,
Mar 07, 2018 Mar 07, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Milos+Draca_70  wrote

I use sessionTimeout function once JavaScript function detects timeout is equal to 0. Then sessionTimeout will get triggered.

There is no need for that. ColdFusion's built-in sessionTimeout is automatically triggered. That is, if the user is inactive within the timeout period, ColdFusion will automatically end his session.

So what you are suggesting is to just clear the session scope and use <cflogout> ?

Yes.

How cflogout will affect the process?

It logs the user out. I am presuming you logged the user in using cfloginuser. Suppose you also use loginStorage = "session". Then, throughout the session, ColdFusion will know the user's username, password and role.

When ColdFusion runs <cflogout> or when the session ends, ColdFusion deletes the username, password and role from memory. The user is no longer logged in. It's the same mechanism whatever the type of sessions you use. Session rotation or invalidation are unnecessary in the login framework.

Votes

Translate

Translate

Report

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 Beginner ,
Mar 08, 2018 Mar 08, 2018

Copy link to clipboard

Copied

Hello,

I looked over your answers and there is few things that I'm not using in my project. My login process doesn't use any of above mentioned methods. To be more specific <cflogin> and <cfloginuser>. That is way I was confused when you placed loginStorage="session" in Application.cfc. However, here is example of my login process:

Login.cfm

Simple login form:

<form name="my_login" id="my_login" class="form-login" autocomplete="off">

                     <div class="form-group">   

                          <input type="text" name="username" id="username" maxlength="50" placeholder="Username" required autofocus />

                     </div>

                     <div class="form-group">

                          <input type="password" name="password" id="password" maxlength="50" placeholder="Password" required />

                     </div>

                     <div class="form-group">

                          <input type="submit" class="btn btn-lg btn-primary btn-block" value="Login" />

                     <div>

               </form>

Next I have is Authentication.cfc

<cffunction name="checkLogin" access="remote" output="false" returnformat="JSON">

    <cfset fnResults = structNew()>

    <cfif (!structKeyExists(FORM, "username") OR !structKeyExists(FORM, "password")) OR (!len(trim(FORM.username)) OR !len(FORM.password))>

         <cfset fnResults.status = "500">

         <cfreturn fnResults>

         <cfabort>

    </cfif>

     <cfquery name="checkUser" datasource="#Application.dsn#">

         SELECT *

         FROM Users

         WHERE UserName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(FORM.username)#" maxlength="50">

     </cfquery>

     <cfset storedPW = checkUser.Password>

     <cfset enteredPW = FORM.password & checkUser.Salt>

     <cfset currentDt = createODBCDateTime(now())>

    <cfif checkUser.recordCount NEQ '1' OR enteredPW NEQ storedPW )>

        <cfset fnResults.status = "400">

        <cfset fnResults.message = "<strong>Error!</strong> Invalid Username or Password!">

    <cfelse>

         <cfset structInsert(SESSION, "UserName", checkUser.UserName, true)>

         <cfset structInsert(SESSION, "UserID", checkUser.UserID, true)>

         <cfset structInsert(SESSION, "Email", checkUser.Email, true)>

         <cfset SESSION.LoggedIn = true>

         <cfset fnResults.status = "200">

    </cfif>

    <cfreturn fnResults>

</cffunction>

On the end my Application.cfc

<cfcomponent output="false">

    <cfset THIS.name = "SinglePageApplication">

    <cfset THIS.sessionManagement = true>

    <cfset THIS.applicationTimeout = CreateTimeSpan(0, 1, 0, 0)>

    <cfset THIS.sessionTimeout = CreateTimeSpan(0, 0, 30, 0)>

    <cfset THIS.setClientCookies = false>

    <cfset THIS.requestTimeOut = "60">

    <cffunction name="onApplicationStart" access="public" returntype="boolean" output="false">

        <cfset APPLICATION.appStarted = now()>

        <cfset APPLICATION.title = "Single Page Application">

        <cfset APPLICATION.dsn = "HearingMaster">

        <cfset APPLICATION.AppStarted = true>

        <cfset APPLICATION.sessionMinutes = 30>

        <cfreturn true>

    </cffunction>

    <!--- Runs when your session starts --->

    <cffunction  name="OnSessionStart" access="public" returntype="void" output="false">

        <!--- Clear the session. --->

        <cfset StructClear( SESSION )>

        <!--- Set loggedin flag to false. --->

        <cfset SESSION.loggedin = false>

        <cfreturn />

    </cffunction>

   

    <!--- Run before the request is processed. --->

    <cffunction name="onRequestStart" returnType="boolean" output="false">

        <cfargument name="thePage" type="string" required="true">

        <cfset REQUEST.appCode = 'SPA'>

        <cfset REQUEST.appName = 'Single Page Application'>

        <cfset var page = listLast(arguments.thePage,"/")>

        <cfif !listFindNoCase("Login.cfm,Authentication.cfc",page)>     

            <cfif structKeyExists(SESSION, "loggedin") AND SESSION.loggedin EQ false>

                <cflocation url="Login.cfm" addToken="false">

            </cfif>

        </cfif>

        <cfreturn true>

    </cffunction>

</cfcomponent>

As you can see above I created login for single page app using Ajax to send request to Authentication.cfc, check the user if user entered correct information I set loggedin flag to true. I store user information inside of the session scope. I'm not 100% positive if I need cflogin/cfuserlogin in this situation. All I was wondering is logout process and what should be done to prevent any attacks. Also to clear everything about the session and the user once they leave the app. Please take a look and let me know if you have any suggestion. Again all of the code is developed from the scratch based on the resources that I found on the web. This is my first project developing login system for single page app. Thanks in advance!

Votes

Translate

Translate

Report

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 ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

That looks good. If it works, then that's okay.

Nevertheless, using cflogin and cfloginuser provide better design. Generally, you will design a site so that any visitor can be tracked by a session while he or she mucks about, without having to log in. Also, a previously logged in user would still be tracked, by means of the same session, even after logging out. That means it isn't optimal to store personal information such as username, ID and password in the session.

    <cfset structInsert(SESSION, "UserName", checkUser.UserName, true)>

     <cfset structInsert(SESSION, "UserID", checkUser.UserID, true)>

I would change that to:

<cflogin>

   <cfloginuser name = "#checkUser.UserName#" password = "#checkUser.UserID#" />

</cflogin>

Henceforth, throughout the application, the username will be available from as getAuthUser(). Quite cool as a check, because you don't have to bother about the session.

If the current user is not logged in, getAuthUser() will return an empty string. Also, getAuthUser() will return an empty string after ColdFusion executes <cflogout>. The session may then continue, but the user is logged out.

For example, think of a webshop. Any visitor can select orders and fill a shopping-cart. That is only possible because a session is tracking the unknown user. We can imagine that session.shoppingcart plays an important part. It's only when the visitor wishes to place an order that we require a login. Preferably within the same session!

Votes

Translate

Translate

Report

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 Beginner ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

I read on one post that cflogin has some kind of issues that's why I have used SESSION scope. One more question, many people use

<cfcookie name="jsessionid" expires="Now" />

In their Log out functions. I'm wondering if that is necessary since you mentioned that we should let ColdFusion take care of ending sessions? If I use cfcookie expires I notice that new session will be established every time I logout and then log back in the system.

Votes

Translate

Translate

Report

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 ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

It is not necessary to delete the cookie when the login expires, or when the session expires.

Dave Watts, Fig Leaf Software

Votes

Translate

Translate

Report

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 Beginner ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

Is that security risk leaving session open? I read few blogs and as you can see above everybody suggesting not to end the session once user Logs out. I'm not sure what is the best way to handle the situation if user log out or close the browser.

Thank you,

Votes

Translate

Translate

Report

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 ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

A session that contains personal data is a security risk. But, in your application, all personal data is cleared from the session when the user logs out. A session that only has a session ID is no risk.

In fact, it might even be better to delete personal data selectively using structDelete. That is, instead of structClear. This ties in with what Dave has just said.

Votes

Translate

Translate

Report

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 Beginner ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

Why

structDelete()

is better option than clearing the session?

Votes

Translate

Translate

Report

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 ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

It's better because you already have a session, and there's no point in deleting it. Deleting and creating things unnecessarily has a cost to it.

Dave Watts, Fig Leaf Software

Votes

Translate

Translate

Report

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 ,
Mar 09, 2018 Mar 09, 2018

Copy link to clipboard

Copied

LATEST

StructDelete is selective. For example,

<cfif structKeyExists(session, "username")>

    <cfset structDelete(session, "username")>

</cfif>

deletes only the username from the session.

StructClear deletes all the data from the session scope, including system keys that ColdFusion uses to identify the session, for example, session.CFID, session.CFToken and session.sessionID.

Votes

Translate

Translate

Report

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
Documentation