Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

CFLOGIN Clearing Session Variables When Browser is Closed

Posted on 2008-10-14
7
Medium Priority
?
2,068 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  

 

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

Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

Question has a verified solution.

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

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…
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…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

705 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