Skip to main content
May 7, 2009
Question

Session variables are set, then immediately disappear. What now?

  • May 7, 2009
  • 1 reply
  • 25484 views

Ok, this is strange. Maybe because I'm darn tire. But anyway...

I have a simple login script that checks stuff and then if successful logs them in via setting session variables into the session via a struct like so:

<cfset session.user = {} />

I then set all my other user specific stuff in this struct. That's straightforward...and when I dump session.user...it shows the data. However, if I refresh the page, this session variable disappears. If I simply dump "session" then I see the usual CFID and CFTOKEN stuff. So session is enabled and ready, but why then does it disappear?

I have done stuff like this before so I really can't see what's happening. The session timeout is also set to 30 minutes in the Application.cfc so that shouldn't be it.

My CFC code is below.

Many thanks,

Mikey.

==================================

<cffunction name="authenticateUser" returntype="void" output="true" access="public" displayname="authenticateUser">

        <cfargument name="userName" type="string" />
        <cfargument name="userPassword" type="string" />
        <cfargument name="userCaptcha" type="string" />
        <cfargument name="userCaptchaEncrypted" type="string" />
       
        <cfset var local = {} />
        <cfset local.fieldsValid = true />

        <cfif not len(trim(arguments.userName))>
            <cfset request.messagesObject.addMessage("info","User name is required.") />
            <cfset local.fieldsValid = false />
        </cfif>
       
        <cfif not len(trim(arguments.userPassword))>
            <cfset request.messagesObject.addMessage("info","Password is required.") />
            <cfset local.fieldsValid = false />
        </cfif>
       
        <cfif not len(trim(arguments.userCaptcha))>
            <cfset request.messagesObject.addMessage("info","The security code is required.") />
            <cfset local.fieldsValid = false />
        <cfelse>
            <cfif not trim(arguments.userCaptcha) eq decrypt(arguments.userCaptchaEncrypted,"iloveyou","CFMX_COMPAT","Hex")>
                <cfset request.messagesObject.addMessage("error","The security code entered was incorrect.") />
                <cfset local.fieldsValid = false />
            </cfif>
        </cfif>
       
        <cfif len(trim(arguments.userCaptcha)) neq 5>
            <cfset request.messagesObject.addMessage("info","The security code must be 5 characters in length.") />
            <cfset local.fieldsValid = false />
        </cfif>
       
        <cfif not len(trim(arguments.userCaptchaEncrypted))>
            <cfset request.messagesObject.addMessage("error","The encrypted security code is required by the system but was not found.") />
            <cfset local.fieldsValid = false />
        </cfif>

        <cfif local.fieldsValid>
       
            <!---<cftry>--->

                <cflock name="lockGetUser" type="exclusive" timeout="30">
               
                    <cfquery name="local.qryGetUser" datasource="#request.dsn#" username="#request.username#" password="#request.password#">
                    SELECT userID, userName, userPassword, userRole, userDeleted
                    FROM #request.tbl_users#
                    WHERE userName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.userName)#" />
                    AND userPassword = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.userPassword)#" />
                    AND userDeleted = 0
                    </cfquery>
                   
                </cflock>
               
                <cfif local.qryGetUser.recordcount eq 1>
               
                    <cflock scope="session" timeout="30" type="exclusive">
                   
                        <cfset session.user = {} />
                        <cfset session.user.username = local.qryGetUser.userName />
                        <cfset session.user.role = local.qryGetUser.userRole />
                        <cfset session.user.id = local.qryGetUser.userID />
                       
                        <cfdump var="#session.user#" />
                       
                    </cflock>

                    <cfset request.messagesObject.addMessage("ok","Welcome " & htmlEditFormat(local.qryGetUser.userName) & ". You have been logged in.") />

                <cfelse>   
                    <cfset request.messagesObject.addMessage("error","Invalid user name / password combination.") />
                </cfif>
   
                <!---<cfcatch type="any">
                    <cfset request.messagesObject.addMessage("error","authenticateUser() " & cfcatch) />
                </cfcatch>
   
            </cftry>--->
           
        </cfif>
       
    </cffunction>

    This topic has been closed for replies.

    1 reply

    BKBK
    Community Expert
    Community Expert
    May 7, 2009
    <cfset session.user = {} />

    That's dicey! I expected the done thing, namely, <cfset session.user = "">. Could you show us the code in Application.cfc? That's where the engine usually needs oiling.

    May 7, 2009

    Hi BKBK,

    <cfset session.user = {} /> is a shorter way of doing: <cfset session.user = structNew() /> in CF8. Is this a bad way of doing things?

    I wanted to create another struct in the session because it makes more logical sense in most of my code to say something like session.user...and I can have other things like session.pages.

    My Application.cfc code is below:

    =====================================

    <cfcomponent output="false">

    <cfsetting enablecfoutputonly="no" />

        <cfprocessingdirective suppresswhitespace="yes" pageencoding="utf-8">
       
            <cfset this.name = hash(now(),"md5","utf-8") />
            <cfset this.applicationTimeout = createTimeSpan(0,0,30,0) />
            <cfset this.clientManagement = true />
            <cfset this.clientStorage = "cookie" />
            <cfset this.loginStorage = "session" />
            <cfset this.sessionManagement = true />
            <cfset this.sessionTimeout = createTimeSpan(0,0,30,0) />
            <cfset this.setClientCookies = true />
            <cfset this.setDomainCookies = true />
            <cfset this.scriptProtect = true />
           
            <cffunction name="onApplicationStart" returntype="boolean" output="true">

                <cfset application.userObject = createObject("component", "cfc.user").init() />
                <cfset application.udfObject = createObject("component", "cfc.udf").init() />
                <cfset application.uploadObject = createObject("component", "cfc.upload").init() />
               
                <cfreturn true />
               
            </cffunction>
           
            <cffunction name="onRequestStart" returntype="boolean" output="true">
           
                <!--- Database Details --->
                <!--- I've taken out sensitive data that is here, like DB tables etc --->
               
                <!--- File Uploads In Bytes --->
                <cfset request.fileUploadLimit = 4194304 />
               
                <!--- Application Authentication --->
                <cflock scope="session" timeout="30" type="exclusive">
                    <cfif not isDefined("session.user") and getFileFromPath(cgi.script_name) neq "login.cfm">
                        <cflocation url="#getDirectoryFromPath(cgi.script_name)#login.cfm" addtoken="no" />
                    </cfif>
                </cflock>
               
                <!--- Application Logout --->
                <cfif isDefined("url.logout") and url.logout eq "true">
                    <cfinvoke component="#application.userObject#" method="logoutUser" />
                    <cflocation url="#getDirectoryFromPath(cgi.script_name)#login.cfm" addtoken="no" />
                </cfif>
               
                <!--- Get all items --->
                <cfquery name="variables.getItems" datasource="#request.dsn#" username="#request.username#" password="#request.password#">
                SELECT *
                FROM #request.tbl_items#
                </cfquery>
               
                <cfset request.itemObject = createObject("component", "cfc.item").init(variables.getItems) />
                <cfset request.uiObject = createObject("component", "cfc.ui").init(variables.getItems) />
                <cfset request.positionObject = createObject("component", "cfc.position").init(variables.getItems) />
                <cfset request.messagesObject = createObject("component", "cfc.messages").init() />
                <cfset request.insertObject = createObject("component", "cfc.insert").init() />
                <cfset request.updateObject = createObject("component", "cfc.update").init() />
                <cfset request.selectObject = createObject("component", "cfc.select").init() />

                <cfreturn true />
           
            </cffunction>

            <cffunction name="onRequest" returnType="void" output="true">
                <cfargument name="thePage" type="string" required="true" />
                <cfinclude template="#arguments.thePage#" />
            </cffunction>
           
            <cffunction name="onRequestEnd" returnType="void" output="false">
                <cfargument name="thePage" type="string" required="true" />
                <!--- Ending requests --->
            </cffunction>
           
            <!---
            <cffunction name="onError" returntype="void" output="true">
           
                <cfargument name="Except" required="true" />
                <cfargument name="EventName" type="String" required="true" />

                <cflog file="skyliteCMS_generalExceptions" type="fatal" application="yes" text="Event: #arguments.eventName#." />
                <cflog file="skyliteCMS_generalExceptions" type="fatal" application="yes" text="Message: #except.message#" />

                <cfmail to="#request.adminEmail#" from="Skylite CMS" subject="Skylite CMS Exception" charset="utf-8" type="html" server="#request.adminEmailSMTP#" username="#request.adminEmailUsername#" password="#request.adminEmailPassword#">
                    <p>An exception ha occured:</p>
                    <p>#except.message#</p>
                </cfmail>
               
                <cfinclude template="error.cfm" />
                <cfabort />
        
            </cffunction>
            --->

            <cffunction name="onSessionStart" returnType="void" output="false">
                <!--- Log database stuff here --->
            </cffunction>
           
            <cffunction name="onSessionEnd" returnType="void" output="false">
                <cfargument name="sessionScope" type="struct" required="true" />
                <cfargument name="appScope" type="struct" required="false" />
                <!--- Log database stuff here --->
            </cffunction>
       
        </cfprocessingdirective>

    </cfcomponent>

    =============================================

    I know some of that code is bad, but I'll sort that one! Just can't understand why the session disappears.

    ALSO, I noticed that when I dump out #session#, everytime I refresh the page, sessionid is new every time. Is this normal? Surely we have one ID per session? It seems like it keeps wiping the session every time. Almost like it IS SETTING it but then clearing it at the same time.

    Thanks for the help!

    Mikey.

    May 7, 2009

    CRAP!!!!!

    I knew it was simple. This line seems to be the culprit:

    <cfset this.name = hash(now(),"md5","utf-8") />

    My app had a new name everytime and must have been resetting itself due to its random construction.

    I'm such a monkey! Thanks for your help though

    Mikey.