Copy link to clipboard
Copied
I have allowconcurrent set to FALSE for my CFLOGIN, and it works the way the documentation suggests: if someone starts a new session from a different browser or computer using the same credentials, the original session's Auth User is set to null (GetAuthUser() EQ ""); it's easy for me to detect this and clear the old user's information.
But this is the opposite of what I need. I want to trust the original session, and prevent any other user from logging in with those credentials while the first session is open. I can't figure out how to do that.
Is there any way to detect in advance that the session for a particular credential already exists, and log out the NEW session instead of the OLD session? Or, rather, prevent the New session from being logged in at all? <cflogout session="others"> seems again to be weighted toward the new session always being the valid one, and that's not what I need.
Thanks for your advice!
Your last post raises an interesting issue. I now realize there are 2 possible cases:
Case 1 is tacitly assumed in the suggesti
...Copy link to clipboard
Copied
Create a unique string based on some combination or hash of the user's username and password. Let's call the string usernamePasswordCode. Then use it to track when the user logs in or out.
For example, during login validation, check whether the key "#usernamePasswordCode#" exists in the session struct and whether the key "isLoggedIn" exists in the struct session["#usernamePasswordCode#"].
If both keys exist and if session["#usernamePasswordCode#"]["isLoggedIn"] is true, then do not proceed with the new login.
If either key doesn't exist or if both exist and session["#usernamePasswordCode#"]["isLoggedIn"] is false, then proceed with the login.
Immediately after the user logs in, set:
session["#usernamePasswordCode#"]["isLoggedIn"]=true;
When you log a user out, set
session["#usernamePasswordCode#"]["isLoggedIn"]=false;
Copy link to clipboard
Copied
Thanks! I've tried this any number of ways, but the second attempt always takes priority:
1. User A signs in, sets session[id]["isLoggedIn"] variable (confirmed by dump); IsUserLoggedIn() returns YES.
2. User B signs in with the same credentials from a different browser; duplicate session[id]["isLoggedIn"] variable is set, and IsUserLoggedIn() returns YES.
3. User A: IsUserLoggedIn() returns NO.
Clearly I am still missing something.
Copy link to clipboard
Copied
I can't tell if you're replying oniy to bkbk or also my separate comment. Only mine talks about isuserloggedin, but you mention it now in your reply here.
To be clear, I was proposing you test the isuserloggedin BEFORE letting them EVEN TRY to do your cflogin code.
If you feel it makes sense, please reply to that other comment thread below, where my focus was only on isuserloggedin.
Copy link to clipboard
Copied
2. User B signs in with the same credentials from a different browser; duplicate session[id]["isLoggedIn"] variable is set,
By @Magnolia2310483946uv
No. You have to check session[id]["isLoggedIn"] before signing User B in. If the variable exists and is true, then you won't have to sign B in. In other words, there is no such thing as a duplicate session[id]["isLoggedIn"] .
3. User A: IsUserLoggedIn() returns NO.
Do you still have allowconcurrent set to FALSE in CFLOGIN? If so, that will explain why isUserLoggedIn() returns NO at step 3.
That is because, in step 2, you apparently proceeded to log User B in. Whereas you shouldn't have. As I said in my first post,
"...check whether the key "#usernamePasswordCode#" exists in the session struct and whether the key "isLoggedIn" exists in the struct session["#usernamePasswordCode#"].
If both keys exist and if session["#usernamePasswordCode#"]["isLoggedIn"] is true, then do not proceed with the new login."
Copy link to clipboard
Copied
Magnolia it's all on you to decide how to handle such things. It's not a feature of cf login or cfloginuser. Instaed, check out the isuserloggedin() function. Use that to decide whether to let them login if someone else is already.
That said, do beware that someone may get frustrated by that behavior, if they wanted to login on another. Being told they have to first logout on the other may be annoying. But if you need to provide that, this should do it.
There's not much to the docs for the function :
Let us know of thus works or if you'd already considered it.
Copy link to clipboard
Copied
Thanks! I feel I must be missing something elementary here.
Here's what I think I'm seeing: IsUserLoggedIn() doesn't take a parameter to specify an ID -- which is probably a good thing -- and there is no Current User to check until login time. I can log in the first session, check to see that IsUserLoggedIn() returns YES, and then log in with the second session. After I log in on the different session with the same credentials, IsUserLoggedIn() for the second session returns YES; and because CF now knows what user I'm signing in as, the Concurrent Session limitation kicks in and the first session returns NO for IsUserLoggedIn() -- also, getAuthUser() returns null. I can't figure out how to get CF to recognize that the prior session should take precedence.
I'm sure it's obvious to you what I'm misunderstanding, but I'm at my wits' end. Thanks for any further help you can provide!
(I know concurrent sessions can be a good thing, especially for me when I'm troubleshooting browser issues; but this is an inflexible requirement and I have no choice.)
Copy link to clipboard
Copied
Your last post raises an interesting issue. I now realize there are 2 possible cases:
Case 1 is tacitly assumed in the suggestions I have given. I don't expect the suggestions to work for Case 2. In other words, I don't expect session app1_xyz987 to have access to a variable defined in session app1_abc123.
You can get a solution for both Case 1 and Case 2 as follows. Use the suggestion I've given, but with one exception. Instead of
session[id]["isLoggedIn"]
use
application[id]["isLoggedIn"]
Copy link to clipboard
Copied
Here's what I think I'm seeing: IsUserLoggedIn() doesn't take a parameter to specify an ID -- which is probably a good thing -- and there is no Current User to check until login time. I can log in the first session, check to see that IsUserLoggedIn() returns YES, and then log in with the second session. After I log in on the different session with the same credentials, IsUserLoggedIn() for the second session returns YES; and because CF now knows what user I'm signing in as, the Concurrent Session limitation kicks in and the first session returns NO for IsUserLoggedIn() -- also, getAuthUser() returns null. I can't figure out how to get CF to recognize that the prior session should take precedence.
By @Magnolia2310483946uv
I think you understand it correctly. That is the behaviour we expect of ColdFusion.
... there is no Current User to check until login time. I can log in the first session, check to see that IsUserLoggedIn() returns YES, and then log in with the second session.
Oh, no. 🙂
If in your check isUserLoggedIn() returns yes, then you should NOT proceed to "log in with the second session". Charlie had already said that:
"test the isuserloggedin BEFORE letting them EVEN TRY to do your cflogin code."
Copy link to clipboard
Copied
There is another factor you might want to consider. If only for completeness.
In Application.cfc, I would set
<!--- the default value is "cookie" --->
<cfset this.loginStorage="session">
Copy link to clipboard
Copied
are you now happy with the sessions?
Copy link to clipboard
Copied
Thanks for all your help! Sorry for the delay responding -- I've had other equally frustrating things to deal with.
Short answer: Yes and No. My situation resembles your Case 2 above, so I think I may have to go with the Application variable technique you suggested.
That being said:
"test the isuserloggedin BEFORE letting them EVEN TRY to do your cflogin code."
I can't figure out how to check the value for IsUserLoggedIn() before a user logs in. The function does not accept a parameter to allow me to check a user beforehand; and when the ID is available after login, it's too late. What am I missing?
Thanks again!
Copy link to clipboard
Copied
I can't figure out how to check the value for IsUserLoggedIn() before a user logs in. The function does not accept a parameter to allow me to check a user beforehand; and when the ID is available after login, it's too late.
By @Magnolia2310483946uv
Let's assume the function you're talking about is a function to log a user in. If so, you could just impose a condition on calling the function. That is, bypass the function if the user is logged in. Something like this:
if (!isUserLoggedIn()) {
// login code that includes the call to the function
}
Copy link to clipboard
Copied
I understand that: that's basically how login functions work in general. But it still results in the same issue, because the problem isn't calling the function when a user is not logged in, but rather after the user is. It's always going to be throwing off the first user while allowing the second exclusive access.
I will mark your previous answer as the correct one... even if it doesn't answer my exact question, it suggests the way forward. Thanks!
Copy link to clipboard
Copied
Magnolia, how did things resolve?
Copy link to clipboard
Copied
Thanks, Charlie -- I'm going to try to demonstrate to the Powers-That-Be that concurrent logins result in discrete session IDs (BKBK's Case 2 outlined above), which should give me a good argument for allowing concurrent logins so long as I audit them rigorously. I plan to adapt BKBK's suggestion about tracking logins in an Application variable -- though I plan to use this primarily to try to detect concurrent logins from different IPs, which would be anomalous to our environment and really would be a cause for concern.
Now I have to go on to other problems that are much more serious...