2
votes

I need to limit only one login in that way, so that user can't login using one account multiple times at once. Also user can be logged on a different server, so I can't use session_destroy, I need to delete session "manually".

When using session with file storage it works fine, I delete file, login new user all works great. However when I use sessions with memcache, I can delete session from memcache, but further login in the same request is lost.

This is how I do it:

session_regenerate_id();
$session_id = session_id(); 

$m = new Memcache();
$m->connect('XXX.XXX.XXX.XXX', 11211);

$ans = $m->delete(SESSION_ID_OF_ALREADY_LOGGED_USER);

$query = "UPDATE activeLogins SET activeSession = '{$session_id}' WHERE userEmail = $safeEmail LIMIT 1";
$dbh->exec($query);

//Login new user...

Any idea what may be wrong?

1
Your login and session/memcache storing process is a bit unclear atm. Any more code snippets/explanations? - ToBe
@ToBe Login is simple storing session variable to true. Memcache session storage is changed in php.ini by changing session.save_handler and session.save_path. Additionally I found out this When the page is complete it pushes the data now in the session to memcached. That last step is kind of critical, because it’s what’s controlling the expiry of the data within memcached. Found here - Dexa
Did you verify that your session using memcache is actually working? If in doubt, create a very small PHP file to rule out any errors in your code and try there with one session variable. - ToBe
Session does work, I connected to memcache server over ssh, made query for particular session id and I do see results. As I said even this delete part works, but it's executed on the end of page, and every writing to session after delete statement is not stored in memcache. Hmm actually now that I think of, something is stored to session after delete statement (encoded data so can't really see) but user is not set as logged in... I'll test in external file. Tnx. - Dexa
No, the session works if your session handler stores it's info AND it also retrieves it from memcache. You should never have to manipulate that memcache yourself as it could actually lead to corrupted session. Try to delete the variable inside the session though the normal session mechanisms. Do not access memcache directly. - ToBe

1 Answers

2
votes

Check the session id against what's stored in the database

As I understand it you want to restrict one user to one client machine. And that machine should be the last one that was logged into. I think you should be able to achieve this with a simple check on each page load.

From your question I can see that your database has a table called activeLogins containing at leat these fields: activeSession and userEmail.

From this I assume that it is the email address that uniquely identifies the user. So after a new login you have a $session_id, $safeEmail and the corresponding updated row in activeLogins table.

Now suppose the user didn't log out of an old machine? What will happen on the next page load there (before you update the activeLogins table)? Right, the activeSession will be different from the $session_id on that server. Remember that the new login changed it.

So all you need to do is check whether the $session_id matches the activeSession in the activeLogins table.

I also would suggest to only update the activeLogins table after a new login, and not on each page load. Although it is not clear from your question whether or not you do this.

I'm not sure whether this does actually answer your question. It seems such a simple answer. However you question is not very clear. Are you really using the code you show us in that order on each page load?!

In response to all your answers I've looked for the best way to push notifications from the server to the client machine. One method you've mentioned yourself is ajax polling, but I think this is a bad practice and should not be used.

There is Ratchet (http://socketo.me) it gives you a continueous connection. You can simply remove the connection when another login is detected and react to that in the old client.

There's also a higher level interface for sending events from the server to a client:

https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events

But that's not supported in IE, so it is not generally usable.

You can also have a look at http://pusher.com

The point of all these suggestions is that you can efficiently push out a signal to a client, indicating that it should remove access to the site you're serving, without constantly polling.