Welcome Guest, Not a member yet? Register   Sign In
Logout user if role is changed mid-session
#1

I am developing a login system where there are multiple user roles (admin, editor, user, etc).  What is the best way to immediately destroy the session of a user that is currently logged in if their user role is changed by an admin? 

For example, user [email protected] has a current role of "editor" which allows him to add and edit newsletters on the site.  He has proven himself to be a bad content manager, but he still must be able to read those newsletters.  The admin has been asked to demote sneaky's role from "editor" to "user" which only has read access to the newsletters.  The admin changes his role immediately, but [email protected] was logged in at the time.  He is still identified as an "editor" by his active session.  Sneaky needs to be logged out right away and forced to log back in for his new "user" role to take effect.  What is the best way for sneaky's session to be automatically destroyed when his role is changed by the admin?
Reply
#2

Since storing sessions is tricky when it comes to systems running on multiple instances behind a load-balancer, I simply store an UUID in the session cookie and store the connection between the UUID and the user's account in a table in the database. Incoming requests are checked for the cookie and the UUID is looked up in DB and the user is found.

In you case, after editing the user's permissions it would be possible to lookup the user's UUID and remove that in either database or Redis. This would force the user's session to be invalid.
Reply
#3

(This post was last modified: 07-28-2020, 06:41 PM by mlurie.)

Thanks for pointing me in the right direction, tgix. I added a table to my database to store Session IDs and User IDs.  I updated my setUserSession private method to insert these records in the database whenever a user logs in.  Then I created a destroyUserSessions method that can be called when a user logs out and when an admin updates or deletes a record from the User table in the database.

PHP Code:
private function setUserSession(array $user) {
        session()->set('UserID', $user['UserID']);
        session()->set('FirstName', $user['FirstName']);
        session()->set('LastName', $user['LastName']);
        session()->set('Email', $user['Email']);
        session()->set('Role', $user['Role']);
        session()->set('LoggedIn', TRUE);

        $session_model = new SessionModel;
        $session_model->where('UserID', $user['UserID'])->delete(); //Clean up old sessions

        $session_data = [
            'SessionID' => session_id(),
            'UserID' => $user['UserID'],
        ];
        $session_model->insert($session_data);
    }

    public function destroyUserSessions($user_id = -1) {

        //Build array of sessions for UserID
        $session_model = new SessionModel;
        if($sessions = $session_model->where('UserID', $user_id)->findAll()) {
            
            
//Check for existing session
            if(session_id()) 
                session_write_close
();              //Save existing session data and release lock

            session_start();                        //Start/resume Session
            $current_session_id = session_id();     //Backup current Session ID
            session_write_close();                  //Save session data and release lock

            //Destroy sessions matching UserID
            foreach($sessions as $session) {

                session_id($session['SessionID']);  //Specify Session ID
                session_start();                    //Start specified Session
                session_destroy();                  //Destroy specified Session
                session_write_close();              //Save session data and release lock
            }

            session_id($current_session_id);        //Set original Session ID
            session_start();                        //Resume original session
            session_write_close();                  //Save session data and release lock

            //Delete all sessions for UserID from the database
            $session_model->where('UserID', $user_id)->delete();
        
Reply




Theme © iAndrew 2016 - Forum software by © MyBB