RE: [coldbox:16904] Caching

The session storage plugin is just a wrapper for the session scope which CF manages. Where are you storing user data? My first thoughts are that you either are passing something by reference and storing the same instance of your user object in all sessions, or you tried to inject a transient object into a singleton (ie a user object into the user service) and are suffering from scope widening injection.

Show us some code regarding where you are storing user data, any objects you are creating that contain user data, and how those objects are being persisted.

I’d also like to make a quick PSA for having a production-like staging environment for testing :slight_smile:

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Brad, thanks for replying, I’ve found some other posts that seem to be pointing out the same issue, but I’m having trouble figuring out where I went wrong.

Here is the opening of my security manager plugin:




I’m checking for the user session by calling the getUserSession() function in my UserService:

The UUID’s are different.

Here is authenticateUser:




<cfset oUser = getUser(argumentCollection=arguments) />
<cfset instance.SessionStorage.setVar(‘CurrentUser’, oUser) />
<cfset instance.sessionstorage.setVar( ‘roles’, oUser.getRoles()) />

<cfif len(oUser.getUserid() GT 1)>

You’ll probably also want to see this:

<cfif username NEQ “”>
<cfset qResult = instance.UserGateway.getBy(prop=‘username’, val=arguments.username) />
<cfelseif userid GT 0>
<cfset qResult = instance.UserGateway.getBy(prop=‘userid’, val=arguments.userid) />
<cfelseif email NEQ “”>
<cfset qResult = instance.UserGateway.getBy(prop=‘email’, val=arguments.email) />

<cfif isDefined(“qResult.recordcount”)>

<cfset oUser = instance.BeanFactory.populateFromQuery(oUser, qResult)>

I REALLY appreciate your time, but I’m still confused as to why this doesn’t happen when ConfigAutoReload is on.

Because Config Auto Reload is reloading all the objects into memory, which kind of indicates that the session is being held by the browser even if you have logged off.

I have noticed a lot of places where you are NOT scoping you variables, and could be a major cause of this, but I am almost going to suggest that you have information being stored in a singleton that is holding the information as well.

Also double check that you’re expiring the cookies in your application, I think you need to sit down with a line debugger and watch the request come into the server, and then watch when and what is stored in the application and session. It might be pain staking to do, but I am almost confident that this is a combination of you not scoping your variables, and singleton like components are holding information that they should not be holding.

Andrew, I appreciate the response and I’m not trying to be argumentative, you’re probably right about the scoping and/or singleton. What I don’t get is why multiple users can login to different accounts from multiple computers and everything works fine, as long as ConfigAutoReload is set to true. I would think that is the memory was being reloaded their sessions would be wiped out.

When ConfigAutoReload is off I seem to be able to grab the current user’s object out of sessionstorage from anywhere in the application and it appears to be correct. Example, if I’m not logged in the username in sessionstorage is an empty string, but when I access it from the interceptor it gets the information from first user object it loaded since reinit. I also read that all interceptors are singletons. Should I somehow be passing the user object for testing into the security interceptor, rather than reaching out for it from within the interceptor?

I’m shooting in the dark at this point, but I noticed that in the interceptor I’m calling sessionstorage like this, oSession = controller.getPlugin(“sessionstorage”), but everywhere else in the application, I’m calling it from instance.getPlugin… I tried instance, but it doesn’t exist in instance in the security interceptor. Sorry, I didn’t write this part of the code and picked it up from someone else, so I’m trying to wrap my head around this.

Could you provide an example of how and where you suggest I could have scoped a var. I thought sessionstorage would be in the session scope by default and I wouldn’t have to otherwise scope information I pulled from it as long as I’m just using it as a local var to the function, that I may or may not return from the function.

Sorry, I think the lack of sleep is messing with my head. I’ve gone down so many different paths trying to figure this out I fear I’m losing my way.

Okay, so this is dirty, but this is what I’ve done. Whenever someone goes to the login page I run this, which is partially the same as having ConfigAutoReload set to true, but only for the login page event:


<cfset application.cbController.getLoaderService().setupCalls(COLDBOX_CONFIG_FILE)>

When I do that then everything works fine. Somehow this is resetting the security interceptor so that is loads the actual current user object instead of the object belonging to the first user who logged in after reinit.I feel like I’m getting closer. Is there another way to I could ‘reload’ the variables that security interceptor uses?

Thanks,
Rob

Mystery solved!

......

VS

<cfelseif isDefined(“rc.username”) AND isDefined(“rc.password”) >

Once I set the non-scoped username and password, the interceptor used the same user/pass combination for every check after that. Hence the same user was logged in for every login request.

Thanks for bearing with me!

Sorry, that was backwards, sort, this is right…

......

VS

<cfelseif isDefined(“username”) AND isDefined(“password”) >

Actually I think that is a misconception on your part, the session storage is just a wrapper, therefore if it is set in the session it remains in the session. Whether you reload the configuration or not.

And your example in the later paragraph, confirms what I stated.