Destroying a specific session in Code Igniter
Asked Answered
T

3

75

I want to be able to log users out of my app built in Code Igniter.

I know how to end an active local session:

$this->session->sess_destroy();

But how can I destroy a session that was started on another computer and thereby log a user out of their session?

I store a unique id associated with their account in the session data, so I can see it in the session table in the database, but it is stored along with the other session data in a column called user_data, the contents of which look something like this:

a:4:
{s:9:"user_data";s:0:"";s:6:"userid";s:6:"189034";s:9:"logged_in";b:1;s:5:"token";i:1767727789;}

where 189034 is the user's id.

So, is there a way to somehow select the row in the session table based on the user's id, and then delete the row and destroy the session. Or is there another way to do this entirely?

Theone answered 5/3, 2012 at 8:35 Comment(0)
A
42

Create a new column in the ci_session table.

ALTER TABLE `yourdatabase`.`ci_sessions` 
ADD COLUMN `userid` VARCHAR(45) NULL  AFTER `user_data` ;

Then in your login function get the id from your login process and before adding the userdata information to the session do:

/* Delete any existing sessions with the current userid session.
Note - a new session has already been generated but doesn't have a value
in the userid column, so won't get deleted. */
$this->db->delete('ci_sessions',array('userid' => $identity));    

// Get the current session and update it with the userid value.
$session_id = $this->session->userdata('session_id');
$this->db->where('session_id', $session_id);
$this->db->update('ci_sessions', array('userid' => $identity));

Where $identity is your userid. That clears any previous sessions and means only one exists at a time.

Auditory answered 5/3, 2012 at 9:40 Comment(5)
Wouldn't you lose the userid value when the session id is regenerated? I thought this was the problem we talked about in the comments?Tritheism
No. When the user logs in from the second machine but before the user is authenticated a new session is created, so at that point there are two records in the database. With the above code, the old session record is destroyed and the new one is simply updated with the session information. I've edited the answer to be a bit clearer.Auditory
I mean when the same session regenerates it's own id. "...the session class will check to see if valid session data exists in the user's session cookie...If a session does exist, its information will be updated ... With each update, the session_id will be regenerated." Am I overlooking something?Tritheism
The key word there is 'updated'. The tuple (record) in the database table is updated, not deleted and inserted. i.e. the SQL code that is run by codeigniter is 'update ci_sessions set session_id = '456def' where session_id = 'abc123'. Therefore maintaining the integrity of the userid column for as long as the session exists.Auditory
In case your using C3 this should be the query: ALTER TABLE yourdatabase.ci_sessions ADD COLUMN userid VARCHAR(45) NULL AFTER data ;Martial
D
6

There is the function to destroy some items/session you want

$this->session->unset_userdata('session_name')

And to allow one user to log in one computer at a time or one browser at a time you can read more here

Allow one session only at a time

Desecrate answered 6/3, 2012 at 14:43 Comment(0)
T
5

One of the problems with serialized data is that there's no legitimate way to query it. You'll have to get all users in the session (could be a lot) and unpack the data, check for the value, then delete the row in the session table, effectively destroying that session.

foreach ($this->db->get('sessions')->result() as $session)
{
    $data = unserialize($session->user_data);

    if ( ! isset($data['user_id'])) continue;

    if ($data['user_id'] === $id_to_delete)
    {
        // delete the row
            $this->db->where('session_id', $session->session_id)
                ->delete('sessions');
    }
}

I would probably discourage this. Every user on your site, logged in or not, has a session that would have to be picked through, and remember: one user could possibly have more than one session so you'd have to cycle through every one.

Another approach could be to add a custom column to the session table with the user id (or a hash of the id). Something that you can query against to find the user's session quickly. Then, when you add the user_id to the session, populate this column, and when you need to delete the session by user_id it can be done quickly and efficiently.

Tritheism answered 5/3, 2012 at 8:59 Comment(2)
I too would discourage this approach. Your second suggestion is more realistic.Auditory
Although it's easiest to just add this function, it's not necessary the best if you have huge session table.Verisimilitude

© 2022 - 2024 — McMap. All rights reserved.