Solved

CFLOGIN Clearing Session Variables When Browser is Closed

Posted on 2008-10-14
7
2,003 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
New My Cloud Pro Series - organize everything!

With space to keep virtually everything, the My Cloud Pro Series offers your team the network storage to edit, save and share production files from anywhere with an internet connection. Compatible with both Mac and PC, you're able to protect your content regardless of OS.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In our day to day coding, how many times have we come across a necessity to check whether a URL is a broken link or not? For those of you that answered countless and are using ColdFusion like myself, then this article is for you.  It will show yo…
Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

929 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

11 Experts available now in Live!

Get 1:1 Help Now