• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2115
  • Last Modified:

CFLOGIN Clearing Session Variables When Browser is Closed

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
matttoca
Asked:
matttoca
  • 4
  • 3
1 Solution
 
SidFishesCommented:
you might just need to use cfparam so the variable is defined (altho no value set)

<cfparam name="session.User.FullName" default="">
0
 
matttocaAuthor Commented:
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
 
SidFishesCommented:
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
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
matttocaAuthor Commented:
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
 
SidFishesCommented:

how about adding

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

to your welcome page
0
 
matttocaAuthor Commented:
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
 
matttocaAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now