Log off target user?

Currently, I have altered the WebUser class to store more information in session. However, I need to wait until everyone logs off and back on again, or temporarily set it to update the session even with cookie logins, before actually applying it in code - both involve arbitrary and unknown wait periods. So, first and foremost, I need to know how to just mass logout every user on my site by invalidating their login information. Emptying the YiiSessions table didn’t do anything, it just regenerates the information as needed, which is pretty creepy.

But, thinking about it, I have more requirements for such a thing. It stands to reason that a site admin ought to have the ability to force logoff people as well, for one reason or another. And it would also be nice if users could logoff their own accounts that are active on other computers.

So I guess I have two questions; how do I obliterate any current login information, and how do I convert, “User 13, session 3, you’re no longer logged in” into code?

This is still very much an issue. I have code ready to deploy, right this minute, but I absolutely need to nuke everyone’s login session and have them log back in so that the UserIdentity and WebUser classes will have the proper information.

The reason why the session table does "restore" deleted session data is because you have CWebUser.allowAutoLogin set to true and you specify a $duration when calling CWebUser::login().

You can do the following, add a column force_logout (BIT(1) OR TINYINT) to the user table. Now when you want to logout all or specific users, delete their records in the session table and set force_logout to 1 in the user table.

Override CWebUser::beforeLogin this way:




class WebUser extends CWebUser

{


   public function beforeLogin($id, $states, $fromCookie)

   {


      if ($fromCookie)

      {

         

         $forceLogout = (bool)Yii::app()->db->createCommand("SELECT `force_logout` FROM `user` WHERE `id` = :id")->queryScalar(array(':id' => $id));


         // We deny login here in case it is initiated from cookie and `force_logout` is set to 1

         if ($forceLogout)

         {

            return false;

         }


      }

      else

      {

         // User logs in the usual way, now we have to set `force_logout` to 0 again

         Yii::app()->db->createCommand("UPDATE `user` SET `force_logout` = 0 WHERE `id` = :id")->execute(array(':id' => $id));

      }


      return true;


   }


}



You may use ActiveRecord instead of createCommand and you may set a flash message to let the user know to login again (if force_logout is 1).

That’s… certainly one way to do it, I suppose.

What if a user is logged in on multiple computers (be it due to actually being logged in, or an account hacking in progress), and I want to snipe just one of those logins?