Hello StackOverflow Community:
Here is a tricky situation. Suppose that 20 users are logged-in to my webapp and I, the admin, (from a different computer and browser) ban 3 of them, how then do I kick out those 3 logged-in users that I just banned? It seems to be a matter of deleting their sessions/cookies, but how do I know which sessions to delete/invalidate and how to access them?
Just so you know, this project is in CakePHP and I’m using Memcache as the engine to store sessions. I already tried an option discussed in the cakephp channel that goes like this:
-
When user log-ins, his session_id (e.g. sd19eIVasdokja021dnasd) is stored in memcached along with his user id (e.g. the one in db: 323). This way, the user’s db record is associated with his session_id within the server. Some code:
Cache::write('user_session_id_' . $this->Auth->user('id'), $this->Session->id()); -
After the model sets the user’s banned column to 1, I lookup if a Memcache key with the user’s id exists, from which I retrieve the session id. I then delete the Memcache key:
if ($this->save(array('User' => array('id' => $userId, 'banned' => 1)), false)) {
$userSessionId = Cache::read('user_session_id_' . $userId);
if ($userSessionId !== false) {
Cache::delete($userSessionId);
Cache::delete('user_session_id_' . $userId);
}
}
-
It doesn’t work, the user is still logged-in. I’m very sure I have to destroy/invalidate cookies though, in which case there is probably no way to alter other users cookies, right?
FOLLOWUP AND SOLUTION:
I was able to solve this by following this…
Remotely destroy a session in php (user logs in somewhere else)?
…and also this (a bit pseudo-code within the User model that actually evolved from my point number two above)(Note that my point number one listed above is also needed, due to line six below):
foreach ($bannedUsers as $userId) {
if ($this->save(array('User' => array(
'id' => $userId,
'banned' => 1,
'ban_date' => date('Y-m-d H:i:s'))), false)) {
$userSessionId = Cache::read('user_session_id_' . $userId);
if ($userSessionId !== false) {
$Session->id($userSessionId);
$Session->write('Auth', '');
Cache::delete('user_session_id_' . $userId);
}
}
}
You seem to be doing something wrong with your app. The idea of the SESSION/COOKIE system is that the SESSION id stored is matched at the beginning of each request made to the server with the COOKIE that the browser sends. If they don’t match, the app simply exits and shows the logon page. Thus, if you are able to delete the SESSION id correctly, there is no way that a particular user is not logged off unless you are not checking the SESSION/COOKIE match that you should at the first line of every page.