Robert Palmer (Yes, THE Robert Palmer), asks:
The short answer is no. CFLOGIN really just provides a way to see if your are logged in, store your authentication information (username), and do simple roles based authorization. Anything outside of that area would have to be customized per your application needs.I have a question about CFLogin. Is there any way to check and see if a username is already in use and prevent the login if it is. I am trying to prevent multiple people from logging in with the same credentials at the same time.
Solving this problem typically involves solutions that aren't going to be perfect. You can keep a RAM based collection of who has logged in easily enough. Just store the list of users in the Application scope. When the user logs out, remove this name. If they forget to logout, just use onSessionEnd to handle it there.
The problem with this solution is that users don't always remember to logout. If they were to switch from Firefox to IE for example (crazier things have happened) and forget to logout, they would not be able to login again. You could also remember their IP address and simply allow multiple logins from the same IP, but that could be compromised as well.
If I had to do this right now, I'd probably just use the Application scope list of usernames. Whats nice about this is that it also gives you some nice metrics you can inspect as well (N users are currently logged in).
Archived Comments
The heck?!
"Robert Allen Palmer (19 January 1949 – 26 September 2003), born in Batley, Yorkshire, was an English singer-songwriter and is now writing CFML from beyond the grave."
Yeah, I was surprised too. I didn't know he had passed.
@Ray
Surprised he'd passed or surprised the afterlife has email?
Heh, the former, not the later. ;)
Ray,
What are your thoughts on using cookies for this in combination with the application scope. So, when a user logs in a session token is served to the user as a cookie. If that user tries logging into the site from another pc the system could invalidate the session token cookie of the other user and allow the second to log in. This would be handy so that if a user forgets to log off the session could be terminated anyway.
Apparently he was addicted to ColdFusion as well as love!
You can't invalidate a cookie like that though. Request A comes from Safari and logs in. You send cookie X to him. Request B comes in from FF. How would you kill the cookie for Safari? Both have the same IP.
Good point. I guess you maybe able to add a column to the users table with the code as well. So, when Request B comes in, it would see that the cookie is different and change it. The only issue though is that I would think every users request would have to verify against the database and that might not be a great thing.
he finds ColdFusion Simply Irresistible
" If they were to switch from Firefox to IE for example (crazier things have happened) and forget to logout,"
That isn't crazy at all. I'm pretty suprised at the creativity of users when it comes to "gaming the system". You tell 'em to not open up multiple windows, and they'll hit you with multiple browsers.
(on an entirely separate note, somebody the other day noted their LylaCapta capta was "bs", and that's what it is now, too. Is this a conspiracy?)
Actually Ray, there is a way. I just wrote up SessionUtility for RiaForge, and now you can traverse session internals to check to see if a person is already logged and even log the former out if needed. I have the code in prod environment for 3 weeks now, working flawlessly. Hope to have the code up soon.
@Sami: How is this different from keeping a list of logged in users anyway? I mean I get how it may be simpler to look at the sessions - I get that - but it doesn't seem like it solves the problem of 2 browsers for example.
I don't have my notes for this in front of me, but I was thinking that you could keep an application scope of the users and the ip addresses. If someone logs in with the same username you update the ipaddress. The next time the first user hits a page your script sees the ipaddress is different and logs them out. This solution wouldn't work for users at the same location / on the same ip, but It would work fine for user sharing via the internet.
@Ray,
It does solve the issue of multiple browser. More details to follow. Trust me, it rocks.
Rays solution works well.
I have a similar solution in place for quite some time.
I have an App scope array called Application.Sessions
and each item is a struct with
username
IP
start_time
last_request
in my OnRequestStart() I check that the user is not already in the Sessions struct and, if they pass validation I add them to it, if they are already there, I simply log them out and back in.
This may not work for all because its an internal app that uses Windows login credentials and no login form at all.
it checks their browsers client login param and if its there, checks it against the user table. Otherwise its not in the browser so they have not passed windows nt auth.
But the point remains, keep a record of all valid sessions currently in use, use user authentication of some kind and if they pass that, then validate your in memory sessions. if they are not in it, add them if they are in it, alert them they have been logged out.
This is also my session tracker in my admin console to monitor system usage. I actually update the Array with CF Event system and use the sample Flex session manager app to monitor real time. I can even kick them out of my app with the Flex monitor as well as send global and user specific messages.
seems easy to me.
Tim
You can use JavaScript to fire a logout action with "onunload" or something like it. It's not perfect and will not work within browsers that aren't JS enabled, but it is an option.