• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

user struct in session

Participant ,
Jan 19, 2010 Jan 19, 2010

Copy link to clipboard

Copied

Hi,

As part of the user login I am creating session.user variables when user logs in.  It works just fine when user logs in first time or if user logs out and logs back in.  The problem is when the session times out due to timeout setting and user tryies to log back in.  This is when session.user.* no founds error comes out.  I dump the session varables and user settings are nowhere to be found.  Why would user login be any different on time out then after logout?

here is my application.cfc

<cfcomponent>
<cfparam name="loginQuery.news" default="0">
<cfparam name="loginQuery.calendar" default="0">
<cfparam name="loginQuery.account" default="0">
<cfparam name="loginQuery.site" default="0">
<cfparam name="loginQuery.marketing" default="0">
<cfparam name="loginQuery.users" default="0">
<cfinclude template="/Application.cfc">

<cfset This.name = "Login">
<cfset This.Sessionmanagement="True">
<cfset This.clientManagement = "true">
<cfset This.loginstorage = "session">
<cfset THIS.SessionTimeout = CreateTimeSpan( 0, 0, 10, 0) />

<cffunction name="OnRequestStart" >
  <cfargument name = "request" required="true"/>
  <cfif IsDefined("URL.logout")>
    <cflogout>
    <cflocation url="/index.cfm" addtoken="no">
  </cfif>
  <cflogin>
  <cfif NOT IsDefined("cflogin")>
    <cfinclude template="loginform.cfm">
    <cfabort>
    <cfelse>
    <cfif cflogin.name IS "" OR cflogin.password IS "">
      <cfoutput>
        <h2>You must enter text in both the User Name and Password fields.</h2>
      </cfoutput>
      <cfinclude template="loginform.cfm">
      <cfabort>
      <cfelse>
      <cfquery name="loginQuery" dataSource="#Application.DNS#">
            SELECT UserID, UserLevel, news, calendar, site, marketing, account, users
            FROM Users
            WHERE
               UserID = '#cflogin.name#'
               AND Password = '#cflogin.password#'
            </cfquery>
      <cfif loginQuery.UserLevel NEQ "">
     
     
        <cfloginuser name="#cflogin.name#" Password = "#cflogin.password#" roles="#loginQuery.UserLevel#">
        <cfset SESSION.User = StructNew() />
        <cfset SESSION.User.news =  loginQuery.news/>
        <cfset SESSION.User.calendar =  loginQuery.calendar/>
        <cfset SESSION.User.account =  loginQuery.account/>
        <cfset SESSION.User.marketing =  loginQuery.marketing/>
        <cfset SESSION.User.site =  loginQuery.site/>
        <cfset SESSION.User.users =  loginQuery.users/>
       
     
        <cfelse>
        <cfoutput>
          <H2>Your login information is not valid.<br>
            Please Try again</H2>
        </cfoutput>
        <cfinclude template="loginform.cfm">
        <cfabort>
      </cfif>
    </cfif>
  </cfif>
  </cflogin>
</cffunction>
<cffunction name="onSessionEnd">
  <cfset StructClear(Session)>
  <cflocation url="/index.cfm" addtoken="no">
</cffunction>
</cfcomponent>

TOPICS
Advanced techniques

Views

2.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 22, 2010 Jan 22, 2010

I think I've got it: time cflogin out!

<cflogin idleTimeout="600">

I have chosen 600 seconds because it corresponds to the sessiontimeout value of 10 minutes. If you don't state the idletimeout attribute, Coldfusion uses the default value of 1800, which is 30 minutes! Your sessions time out much earlier than that.

Votes

Translate

Translate
Community Expert ,
Jan 20, 2010 Jan 20, 2010

Copy link to clipboard

Copied

Two things:

1) You cannot access the session scope directly in onSessionEnd. Coldfusion therefore does you a favour by passing it as an argument. Instead of

<cffunction name="onSessionEnd">
  <cfset StructClear(Session)>
</cffunction>

do this

<cffunction name="onSessionEnd">
    <cfargument name = "SessionScope" required="true">
    <cfargument name = "AppScope" required="true">
        <cfset StructClear(arguments.SessionScope)>
</cffunction>


2) It looks awkward to include one Application.cfc in another like this: <cfinclude template="/Application.cfc">. It might even be wrong.

You have to let the current Application.cfc inherit from the other. To do so, use the current CFC's extends attribute

<cfcomponent extends="dotted_path_to_parent_Application_file">

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jan 20, 2010 Jan 20, 2010

Copy link to clipboard

Copied

<cffunction name="onSessionEnd">

<cfset StructClear(Session)>

<cflocation url="/index.cfm" addtoken="no">

</cffunction>

Also, onSessionEnd is not associated with a request. So the cflocation probably will not do anything.

<cfparam name="loginQuery.news" default="0">

<cfparam name="loginQuery.calendar" default="0">

Why cfparam a query used in OnRequestStart?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

Thanks for the reply...

My original OnSessionEnd is blank, I was just trying things to see if would help.  I proly do not even need onSessionEnd.

As far as including root application.cfc, that one has all the application settings that are used throughtout the site and then this application.cfc is for the secure folder only.  Session or user settings are not needed for the rest of the site.  It possible that it's bad way of doing it but it works.  I'll look into this bit more later on.  My problem still exists where loging in after session expires the session.users struct does not get created.  I just can't figure out why at all.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

It possible that it's bad way of doing it but it works.

I wouldn't say that, given that you've just reported a problem. I would use the extends attribute instead of the cfinclude tag, if only to eliminate that as the cause.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

I already did, I moved  onApplicationStart from the root application.cfc to this one and removed cfinclude.  I am still getting same problem.  Thanks

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

Ok, now it's time for us to solve the problem. I wish to understand how the session-not-found occurs.

Suppose the session has timed out. Do you get session-not-found after you successfully log in, and then go to a page where the session scope is dumped?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

I don't use cflogin (I prefer my own systems) so I may miss something obvious that has to do with the cflogin functionality but your code at a glance has the right logic.  We still haven't seen the actual error and details (such as all the files called in order to get to it).  Or the included application.cfc.  My bet at this point is it is something in the included application.cfc.  Something is created which causes it to skip the step of either actually logging in or creating the session.user vars.  Perhaps some logic that looks for a var and assumes if it exists then the rest must also be there?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

Also another thought.  Since the application.cfc is only called within the secure folder (or so I understand) maybe when they are timed out they go to the parent root and its application.cfc and thus skip the logic in your sub application.cfc?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

In my opinion,  <cfset SESSION.User = StructNew() /> belongs to onSessionStart.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

Yes I get "User.xyz is undefined in Session" after sucessfull login.  And this only happens when loging in after session expires.  If I invoke the cflogout and log back in again it works just great.  I am using session.user.xyz in the site navigation to hide/show certain menu links.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

Put the following line just before the first place where you attempt to write a session variable (the error message should have told you where that is):

<cfoutput>#getAuthUser()#</cfoutput>

Do you get a non-empty string?

[added: I would, for test purposes, reduce the sessiontimeout to just several minutes]

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

I've placed getAuthUser() on the index page that gets displayed after the successfull login and I am getting the user name that has loged in.  This happens when session.user errors out and when it doesn't.  So I guess it goes fine through the login process.

I've also placed the session user struct creation on onSessionStart

I am still getting user.xyz undefined error

I got my session timeout on 10 seconds.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 21, 2010 Jan 21, 2010

Copy link to clipboard

Copied

I got my session timeout on 10 seconds.

Too small, I think. At least give Coldfusion time to breathe. Two minutes, perhaps? It needs time to clear and restart sessions, load settings, and so on.

I've placed getAuthUser() on the index page that gets displayed after
the successfull login and I am getting the user name that has loged
in.  This happens when session.user errors out and when it doesn't.  So
I guess it goes fine through the login process.

I guess so, too.

I've also placed the session user struct creation on onSessionStart

Still, I would leave it there, as that's the proper place for it to be. You should keep the code to clear the session in onSessionEnd as discussed above

Take the suggestion from -==cfSearching==- and delete the following block. It may have helped you debug, but serves no further purpose.

<cfparam name="loginQuery.news" default="0">
<cfparam name="loginQuery.calendar" default="0">
<cfparam name="loginQuery.account" default="0">
<cfparam name="loginQuery.site" default="0">
<cfparam name="loginQuery.marketing" default="0">
<cfparam name="loginQuery.users" default="0">

However, I believe you had the right intention. I think the following would be better placed in onSessionStart:

<cfset SESSION.User = StructNew()>
<cfparam name="SESSION.User.news" default="0">
<cfparam name="SESSION.User.calendar" default="0">
<cfparam name="SESSION.User.account" default="0">
<cfparam name="SESSION.User.site" default="0">
<cfparam name="SESSION.User.marketing" default="0">
<cfparam name="SESSION.User.users" default="0">

Add the following among the component's fields:

<cfset this.applicationTimeout = createTimeSpan( 1, 0, 0, 0)>

Now comes what I hope will be the breakthrough (assuming that the problem persists). Sessions are bound to the application name, which in turn is stored in the application scope until either the application times out or the server shuts down. It just could be that the application hangs on to old session settings after the session times out.  To verify this, restart Coldfusion. Less drastic alternatives are to change the application name.or to call the method onApplicationStart().

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

BKBK, thanks alot.

I have already tried all those things and the problem persists. I even cloned the whole site on another server and I am getting the same results.  I was just trying to eliminate possibility of bad CF installation or something.

I've been talking to Ban Nadel regarding this problem and he thinks that <cflogin> hangs around bit longer after the session expires which makes alot of sense to me.  That would explain how I am seeing getAuthUser() but it doesn't go through login process under the OnRequestStart.  Since user has not loged out according to CF it just skips funtions in onRequestStart.  That seams to me like a bug in the system.  Is there a better solution for login other then the <cflogin>?

What do you think?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

i thought of that, too. But I felt it was unlikely for that to happen in such a much-used, front-line tag.

I'll post my alternative in a moment. Before that, I have two questions. What is the exact statement of the error message, and on what line does it occur?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

The following code sets the user's session  variables out of the cflogin tag. However, cflogin still exercises influence on the session variables, via getAuthUser(). Also, I cached the query in session scope.If this, too, fails, then check simple things like the spelling of variable names!

<cffunction name="onSessionStart">
    <cfset SESSION.User = structNew()>
    <cfparam name="SESSION.User.news" default="0">
    <cfparam name="SESSION.User.calendar" default="0">
    <cfparam name="SESSION.User.account" default="0">
    <cfparam name="SESSION.User.site" default="0">
    <cfparam name="SESSION.User.marketing" default="0">
    <cfparam name="SESSION.User.users" default="0">
</cffunction>

<cffunction name="OnRequestStart" >
<cfargument name = "request" required="true"/>
<cfif IsDefined("URL.logout")>
    <cflogout>
    <cflocation url="/index.cfm" addtoken="no">
</cfif>
<cflogin>
    <cfif NOT IsDefined("cflogin")>
        <cfinclude template="loginform.cfm">
        <cfabort>
    <cfelse>
        <cfif cflogin.name IS "" OR cflogin.password IS "">
            <cfoutput>
            <h2>You must enter text in both the User Name and Password fields.</h2>
            </cfoutput>
            <cfinclude template="loginform.cfm">
            <cfabort>
        <cfelse>
            <cfquery name="session.loginQuery" dataSource="#Application.DNS#">
            SELECT UserID, UserLevel, news, calendar, site, marketing, account, users
            FROM Users
            WHERE
               UserID = '#cflogin.name#'
               AND Password = '#cflogin.password#'
            </cfquery>
            <cfif loginQuery.UserLevel NEQ "">   
                <cfloginuser name="#cflogin.name#" Password = "#cflogin.password#" roles="#loginQuery.UserLevel#">               
            <cfelse>
                <H2>Your login information is not valid.<br>
                Please Try again</H2>
                <cfinclude template="loginform.cfm">
                <cfabort>
            </cfif>
        </cfif>
    </cfif>
    </cflogin>
    <cfif getAuthUser() is not ""><!--- authenticated user exists --->
        <cfset SESSION.User.news =  session.loginQuery.news>
        <cfset SESSION.User.calendar =  session.loginQuery.calendar>
        <cfset SESSION.User.account =  session.loginQuery.account>
        <cfset SESSION.User.marketing =  session.loginQuery.marketing>
        <cfset SESSION.User.site =  session.loginQuery.site>
        <cfset SESSION.User.users =  session.loginQuery.users>
    </cfif>
</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

I was getting same thing, I think the problem is that the loginQuery does not run since the cflogin has not cleared.

Something like this can work but didn't really wanted to go that way:

<cfif getAuthUser() is not ""><!--- authenticated user exists --->
    <cfquery name="getUser" dataSource="#Application.DNS#">
            SELECT UserID, UserLevel, news, calendar, site, marketing, account, users
            FROM Users
            WHERE UserID = '#getAuthUser()#'
            </cfquery>
        <cfset SESSION.User.news =  getUser.news>
        <cfset SESSION.User.calendar =  getUser.calendar>
        <cfset SESSION.User.account =  getUser.account>
        <cfset SESSION.User.marketing =  getUser.marketing>
        <cfset SESSION.User.site =  getUser.site>
        <cfset SESSION.User.users =  getUser.users>
    </cfif>

thanks

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

I do believe it's OK to do it like that, even in the absence of problems!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

Could you post an exact statement of the error message, and the line on which it occurs?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

I think I've got it: time cflogin out!

<cflogin idleTimeout="600">

I have chosen 600 seconds because it corresponds to the sessiontimeout value of 10 minutes. If you don't state the idletimeout attribute, Coldfusion uses the default value of 1800, which is 30 minutes! Your sessions time out much earlier than that.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

I think you got it.  I've placed the timeout and so far I have not seen any errors.  Thank you very much for your help.  I like this solution much better.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 22, 2010 Jan 22, 2010

Copy link to clipboard

Copied

I think you got it.  I've placed the timeout and so far I have not seen any errors.


Yesss! I am writing to Adobe's Coldfusion team to update the documentation to include a note about the effect of not synchronizing the combined function loginStorage(in session) - sessionTimeout - cflogin.

Every cloud has a silver lining, they say. You and I wouldn't forget that one in a hurry, would we?

I bet it's plain sailing for you from now on. Good luck.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 24, 2010 Jan 24, 2010

Copy link to clipboard

Copied

I am writing to Adobe's Coldfusion team to update the documentation to include a note about the effect of not synchronizing the combined function loginStorage(in session) - sessionTimeout - cflogin.

Done.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 27, 2010 Jan 27, 2010

Copy link to clipboard

Copied

LATEST

Good idea, I am sure there will be others that will run into this issue.  Maybe there is a reason this has been done this way but to me it would make more sense if the cflogin expires on session end.  Anyway, another possibility is to add <cflogout> to OnSessionEnd.  I haven't tried it but I think it would work.

Thanks for all your help BKBK and Ben Nadel!!!

Cheers

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation