Copy link to clipboard
Copied
Does anyone know of a way to end a session (AKA force a user to logout) is the same user name is used to logon somewhere else? I have an application where if a username is used to login twice to the same application AKA the user has two open sessions the previously open session needs to be deleted.
When a user logs on it records there sessionid and user id to a table in the database, so I have the session id of the session i want to kill.
Thank you in advance for any help. Let me know if that still sounds to confusing.
Yes, the code I showed in the other post.
sessionKill.cfm
<cfset structClear(session)>
<!--- This will clear the current session of all data, which should log out any user since the login state is ususlly stored in the session scope --->
Some file somewhere the detects a user has been logged in twice
...<cfhttp url="sessionKill.cfm?cfid=#otherSessionCFID#&cftoken=#otherSessionCFTOKEN#"...>
<!--- This will make an HTTP request passing in the known id and token of a session, that session should then have a
Copy link to clipboard
Copied
You could probably do something using the undocumented and unsupport coldFusion.serviceFactory Java Objects.
But I am not sure that is necessary.
You can delete a session structure pretty simpily.
<cfset structClear(Session)>
If a request was made to a page with the given CFID and CFTOKEN passed in either as get, aka URL or cookie values that session would be accessed.
I think this could be done with a <cfhttp ....> call.
<cfhttp url="sessionKill.cfm?CFID=#dataQry.CFID#&CFTOKEN=#dataQry.CFTOKEN#"...>
Untested and untried, but I think something like this could work.
The session would still exist in the servers memory but it would contain no data.
Copy link to clipboard
Copied
Doi you have any idea what kind of code would go into the sessionkill.cfm page. Here is the problem. A user could be logged onto the application and then go home and log on again before the session times out. I would then kill the session that the user had in the office. Clearing the session would work. That is more of collateral damage to the real problem we are trying to stop. This application is going to be a paid service by amount of user's under a company. AKA company has an account with 100 user's. They pay for each user. We don't want one company to have 1 user and have everyone log onto that 1 user. So we need to log anyone else who is using that user off. Is there some kind of function or code that will do a structClear() of a session that is not the current session?
Copy link to clipboard
Copied
Yes, the code I showed in the other post.
sessionKill.cfm
<cfset structClear(session)>
<!--- This will clear the current session of all data, which should log out any user since the login state is ususlly stored in the session scope --->
Some file somewhere the detects a user has been logged in twice
<cfhttp url="sessionKill.cfm?cfid=#otherSessionCFID#&cftoken=#otherSessionCFTOKEN#"...>
<!--- This will make an HTTP request passing in the known id and token of a session, that session should then have all it's data cleared by the sessionClear() function--->
As I said, this does not actually remove the session from memory of ColdFusion. That can't be done without mucking around with the serviceFactory. But the session will have no data and if a user where to return to it they should not be logged in or have any saved data.
Copy link to clipboard
Copied
I got it working with your help Ian. If you want to see more in depth of how I got it working check it out on my blog at http://cfunderdog.blogger.com/
Copy link to clipboard
Copied
Glad you got it working. But your link does not go anywhere.
Copy link to clipboard
Copied
Sorry it is http://cfunderdog.blogspot.com
Copy link to clipboard
Copied
A couple of follow on suggestions.
1) It is important to note that the StuctClear(session) function does not end the session. The session still exists in the servers memory, the onSessionEnd() function has not fired, and will not until the normal session timeout occurs.
2) With that in mind, it would probably be a good idea to put some message into the session that can be displayed with a user tries to access an existing session. Something like "This session was closed due to multiple access on {date} {time} {ipAddress}" Or something like that.
You have to know, if you just silently kill the session; Schmumbledon is going to come back and complain their application is broken and demand it be fixed because their users are being logged out.
3) I might store the userID, CFID and CFTOKEN values in an Application Structure rather then a database. Then if the ColdFusion server is ever restarted or something else happens there isn't left over data in the database because the normal delete queries did not run.
Copy link to clipboard
Copied
Thank you for the feedback. Those are very good points.
Copy link to clipboard
Copied
Wouldn't putting that stuff start to overload the application after awhile? My company's client is looking to have upwards of a couple thousand user's at one time potentially.
Copy link to clipboard
Copied
You should always be aware of the application load. But a dozen or two characters to store a UserID, CFID and CFTOKEN value times a couple thousand users plus a little overhead for the structure is only a few kilobytes of memory. It would take significantly more concurent users, on the order of hundred of thousands or more, before I would worry about the amount of memory being used by that data.
Copy link to clipboard
Copied
Well I think that I am going to stick to putting the information into the database because even if the Server is restarted when someone logs in it will clear all records that he may have had before.
Copy link to clipboard
Copied
If I understand your question correctly you will need to:
- keep the logged in users into the application scope. A structure
where the user id is the key and the value is a random number (an UUID
is ok);
- when a user logs in you'll check if his id already exists in the
application structure
- if the user is not in the application structure then generate a
random value, save the value to the user session and add a record to
the application structure;
- if the user is in the application and if the value is different
from the value from the user session then this is an attempt to a
second login. Generate a new value and place the value in the
application structure;
- on each request check that the application structure value is the
same as the session value. If not log the user out.
Mack
Copy link to clipboard
Copied
Superficially, it seems to me that all you'd need is a table or list of <user_name, current_session_id, when_started> in some convenient location, and if you determine that the session-ID you have is not the "current" one, go straight for the exit ... giving the user an explanation of what just happened.
The test would, of course, have to be atomic ... properly protected by locks to preclude race-conditions.
The nice thing about this is that you can do it all within the context of the existing session and <cflock> architectures. Instead of actually destroying the other-sessions, you simply render them unusable if anyone happens to wander back into them.