Solved

CFLOGIN Clearing Session Variables When Browser is Closed

Posted on 2008-10-14
7
1,999 Views
Last Modified: 2013-12-24
I have simple application that utilizes the CFLOGIN tag. Here is the code:

<cfapplication name="UserPortal" sessionmanagement="yes" setclientcookies="yes" sessiontimeout="#CreateTimeSpan(0, 0, 15, 0)#" applicationtimeout="#CreateTimeSpan(0, 0, 30, 0)#" loginstorage="session">

<!---Check to see if the application has been initialized.  If not, set the neccesary application variables and initialize the app --->
<cflock timeout="30" throwontimeout="no" type="readonly" scope="application">
      <cfset IsInitialized = IsDefined('application.Initialized')>
</cflock>

<cfif not IsInitialized>
      <cflock type="exclusive" scope="application" timeout="10">
          <cfif not IsDefined('appliaction.Initialized')>
                  <cfset application.DSN = "NSLA2">
                  <cfset application.AdminEmail = "master@nslali.com">
                  <cfset application.Initialized = true>
            </cfif>
      </cflock>
</cfif>

<!--- See if User Logged Out --->
<cfif IsDefined("URL.Logout")>
      <cflogout>
        <cfset URL.Message = "Thank You for Logging Out.">
</cfif>

<cflogin idletimeout="1800" applicationtoken="UserPortal">
      <cfif not IsDefined("cflogin")>
            <cfinclude template="login.cfm">
        <cfabort>
        <cfelse>
            <cfif cflogin.Name is "" or cflogin.Password is "">
                  <cfset URL.Message = "You must enter text in both the Username and Password fields">
                  <cfinclude template="login.cfm">
                <cfabort>
        <cfelse>
              <cfquery name="ValidateUser" datasource="#application.DSN#">
                  SELECT * FROM users WHERE Username = <cfqueryparam value="#cflogin.Name#"
                cfsqltype="cf_sql_varchar" maxlength="255">
            </cfquery>
            <cfif ValidateUser.Roles is "">
            <cfset ValidateUser.Roles = "User">
          </cfif>
            <cfif (ValidateUser.RecordCount) and (ValidateUser.Password is Hash(ValidateUser.Salt & cflogin.Password)) and ValidateUser.Roles is "User">
            <cfloginuser name="#cflogin.Name#" password="#cflogin.Password#" roles="#ValidateUser.Roles#">
                <cflock scope="session" timeout="10" type="exclusive">
                      <cfset session.User = structNew()>
                      <cfset session.User.ID = #ValidateUser.ID#>
                      <cfset session.User.FullName = #ValidateUser.FullName#>
                        <cfset session.User.Company = #ValidateUser.Company#>
            </cflock>
            <cfelse>
            <cfset URL.Message = "Invalid Login. Please Try Again. (You may not sufficient privileges.)">
            <cfinclude template="login.cfm">
                <cfabort>
            </cfif>
        </cfif>
    </cfif>
</cflogin>

I've tried to incorporate :
<cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>
      <cfset cfid_local = Cookie.CFID>
      <cfset cftoken_local = Cookie.CFTOKEN>
      <cfcookie name="CFID" value="#cfid_local#">
      <cfcookie name="CFTOKEN" value="#cftoken_local#">
</cfif>

But what happens is when the browser is closed, it brings the login window up like it should but once the username and password are entered and it tries to access the index page an error pops when I try to call on the variable session.User.FullName. The error states that session.User.FullName does not exist.

I've also tried this:
<cfcookie name="CFID" value="#Session.CFID#">
<cfcookie name="CFTOKEN" value="#Session.CFTOKEN#">

which I found here on this site. But this code doesn't work either. I'm tempted just to leave the users login until the session expires if they don't hit the logout button.

Any suggestions would be great. Or if you find any errors in my code please bring it to my attention.

Thank You,

Matt Toca
0
Comment
Question by:matttoca
  • 4
  • 3
7 Comments
 
LVL 36

Expert Comment

by:SidFishes
ID: 22721236
you might just need to use cfparam so the variable is defined (altho no value set)

<cfparam name="session.User.FullName" default="">
0
 

Author Comment

by:matttoca
ID: 22724101
The thing is that the variable must always have a value.

<cfquery name="ValidateUser" datasource="#application.DSN#">
SELECT *
FROM users
WHERE Username = <cfqueryparam value="#cflogin.Name#" cfsqltype="cf_sql_varchar" maxlength="255">
</cfquery>

This query brings up the username, the hash, their id and fullname among other things. So there should always be a value to put into these statements:

<cfset session.User.ID = #ValidateUser.ID#>
<cfset session.User.FullName = #ValidateUser.FullName#>
<cfset session.User.Company = #ValidateUser.Company#>

For some reason if the user doesn't hit the logout key, they stay logged in when they close the browser and open it again. I researched that how to stop that and found that adding this cfif statement:

<cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>

logouts out the user when they close the browser. But when they try to log back in I get a coldfusion error stating that session.User.FullName doesn't exist and it can't create the page because of that.

What seems to be happening from what I can tell is that the session.User.FullName variable is not getting cleared and when it tries to reload it with the #ValidateUser.FullName# value it cannot. So it states that it doesn't exist. This might not be the case, but if it is how can I get the application to reset the value for session.User.FullName so it can load it with a fresh value from the ValidateUser query?
0
 
LVL 36

Expert Comment

by:SidFishes
ID: 22724310
the cfparam is used to instantiate the variable prior to set it's value to avoid issues of variable not existing when the page loads. This is what seems to be happening in this case

there must be somewhere else in your code that is calling for session.User.FullName as you wouldn't get a does not exist error in

<cfset session.User.FullName = ValidateUser.FullName> (btw you don't need ## inside most cf tags)

check the exact line of the error message





0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:matttoca
ID: 22725562
I've placed the suggested code into the application:

<cfparam name="session.User.FullName" default="">

along with the cfif statement that logs out the user when the window is closed:

<cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>

and it stops the error page from coming up but it makes all of the variables value "'. So when the user logs in and it loads the index page the line of code that greets them:

Welcome <cfoutput>#session.User.FullName#</cfoutput>

outputs:  "Welcome      " instead of "Welcome Matthew Toca".
0
 
LVL 36

Expert Comment

by:SidFishes
ID: 22725702

how about adding

<cfif session.User.FullName eq "">
<cflocation url="login.cfm">
</cfif>

to your welcome page
0
 

Author Comment

by:matttoca
ID: 22726857
Adding:
 
<cfif session.User.FullName eq "">
<cflocation url="login.cfm">
</cfif>  

just created a loop in the application. It would go to the login page and then go back to the login page when the submit button was entered. But this time it put the CFID and CFTOKEN variables in the url.

I was thinking about the application more and thought of something. In order to use the:

<cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>
      <cfset cfid_local = Cookie.CFID>
      <cfset cftoken_local = Cookie.CFTOKEN>
      <cfcookie name="CFID" value="#cfid_local#">
      <cfcookie name="CFTOKEN" value="#cftoken_local#">
</cfif>

is there something I must state in the application tag?

<cfapplication name="UserPortal"
sessionmanagement="yes"
setclientcookies="yes"
sessiontimeout="#CreateTimeSpan(0, 0, 15, 0)#"
applicationtimeout="#CreateTimeSpan(0, 0, 30, 0)#"
loginstorage="session">


0
 

Accepted Solution

by:
matttoca earned 0 total points
ID: 22779467
Alright. So I did some more in depth research and I think I found out what was going on. Apparently the only way to clear session variables when a user closes the browser is to have J2EE Session Management enabled. These statements are from the livedocs:

 "If you use J2EE session management, ColdFusion ends the session and deletes all Session scope variables when the user closes the browser, or if the client is inactive for the session time-out period."

"If you use ColdFusion session management, ColdFusion automatically ends sessions and deletes all Session scope variables if the client is inactive for the session time-out period. The session does not end when the user closes the browser."

I found out that my hosting company does not support J2EE session management. So, it pretty much is impossible for me to clear the session scope.

After thinking for a little bit I think I came up with a solution for my app. By using your cfif statement SidFishes, I can redirect the user to a page when it forces them to log out properly. So when the user forgets to push the logout button I have the:

<cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>
      <cfset cfid_local = Cookie.CFID>
      <cfset cftoken_local = Cookie.CFTOKEN>
      <cfcookie name="CFID" value="#cfid_local#">
      <cfcookie name="CFTOKEN" value="#cftoken_local#">
</cfif>

to reset their CFID and CFTOKEN. Then I place on the index page:

<cfif not IsDefined("session.User.FullName")>
      <cflocation url="logout.cfm">
</cfif>

which directs them to a page that states what just happened and asks them to push a button to logout and have them login again. I could just make it:

<cfif not IsDefined("session.User.FullName")>
      <cflocation url="logout.cfm?logout=true">
</cfif>

but that would be frustrating for a user to login, not knowingly be logged out and then have to re-login again.

Anyway, thank you SidFishes for your help and suggestions.
0

Featured Post

Superior storage. Superior surveillance.

WD Purple drives are built for 24/7, always-on, high-definition security systems. With support for up to 8 hard drives and 32 cameras, WD Purple drives are optimized for surveillance.

Join & Write a Comment

A web service (http://en.wikipedia.org/wiki/Web_service) is a software related technology that facilitates machine-to-machine interaction over a network. This article helps beginners in creating and consuming a web service using the ColdFusion Ma…
When it comes to showing a 404 error page to your visitors, you do not want that generic page to show, and you especially do not want your hosting provider’s ad error page to show either. In this article, I will show you how to enable the custom 40…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now