CodeIgniter Forums
how to destroy a session and immediately create a new one? - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived General Discussion (https://forum.codeigniter.com/forum-21.html)
+--- Thread: how to destroy a session and immediately create a new one? (/thread-29609.html)



how to destroy a session and immediately create a new one? - El Forum - 04-15-2010

[eluser]spot0n[/eluser]
Hi all,
I basically want to do the following:
When a user comes to a site, he can interact with the site and some data will be stored in the session. If he chooses to login, the session data that has been stored till now will be cleared and new session will be started afresh.

Now I cannot use unser_userdata function because some of the userdata's keys are generated on the fly and the key could be anything. So my best bet, as I see is to clear the session somehow and set the username etc for the loggedin user. Then the user can start afresh.

I have the following code, which is not working :

function validateUser()
{
$email = $this->input->post('Email');
$password = $this->input->post('Password');
$isAuthenticUser = $this->Login_model->validateUser($email, $password);

// If the user authenticated properly
if ($isAuthenticUser == TRUE)
{
// Destroy whatever you have in the session
$this->Login_model->destroyUserSession();

// Set the username in the new session
$this->Login_model->setSessionUser($email);
}
}

If I execute this code and then immediately reload the page, the user is not shown as logged in. If I remove the destroyUserSession() call, then the user is shown as logged in.

Interestingly, if I print the session just after destroying it, it seems it is not destroyed at that time. Maybe some sort of delayed destruction which is causing the problem?

Any help is appreciated.
Thanks


how to destroy a session and immediately create a new one? - El Forum - 04-15-2010

[eluser]WanWizard[/eluser]
The session info is cached when the session library is loaded. Calling session->destroy() does delete the session record, but does not clear the session cache. A reload of the page after a destroy should indeed do the trick...


how to destroy a session and immediately create a new one? - El Forum - 04-15-2010

[eluser]spot0n[/eluser]
But I want to reload the page "after" logging the new person in. Otherwise I will have to do two reloads -> One after destroying the session and another after logging the person in. Any simpler way to clear the session cache?


how to destroy a session and immediately create a new one? - El Forum - 04-16-2010

[eluser]spot0n[/eluser]
anyone?


how to destroy a session and immediately create a new one? - El Forum - 04-17-2010

[eluser]Narkboy[/eluser]
I have / had a similar issue with "delayed destruction". Basically, when logging a user out, I called sess_destroy and then loaded a view that said "you logged out". The view contains a login form is the user is logged out, or the user data if they are logged in.

What was happening was that the debug message printing all session userdata indicated that the user had logged out, but the login form was not displayed - it still thought the user was logged in. A refresh made the view work correctly.

Solution: in the login controller, the logout function does this:

Code:
function logout()
{
    if($this->session->userdata('user_name'))
    {
        $this->session->unset_userdata('user_name');
        $this->login_model->do_logout();

        redirect('login/logout/','location');
    }
// Now display the view saying they logged out..
}

Basically, the function checks for the 'user_name' is the session; if it finds it, it deletes it, destroys the session and call itself again. Rinse and repeat. Logging shows that this happens only once, but I don't know why.

I assume that the sess_destroy function actually gets invoked by the destructor and therefore requires the script to run start to finish. By calling a view within the same script as the logout functions, I am effectively acting before the destructor can destroy the session. Just a guess..

Try something similar and see how you get on.

Smile

// Edit - just realise that the code is the dev version before I tidied it up. The logout and user_data delete will both be handled by the login_model. Don't flame me for poor MCV work kthxbye! Big Grin


how to destroy a session and immediately create a new one? - El Forum - 04-17-2010

[eluser]Narkboy[/eluser]
That'll teach me to post mid-way through a problem.

So - it is a caching issue. You do need the refresh. Use a redirect within the logout controller to achieve this. It's invisible to the user, and gets you want you want. My login form checks for a username in the session userdata, and explicitly calling unset_userdata('user_name') clears that. The rest of the userdata remains in the cache. That's no issue for me - as soon as the user goes to the next page, it's gone anyway.

You need to do the refresh so that you can start the session again and add in the data. I would suggest that you store the user name in a temp table in a db to keep it accross the refresh. Otherwise, you'll need to do the refresh and re-send the post data manually.

Smile


how to destroy a session and immediately create a new one? - El Forum - 04-17-2010

[eluser]spot0n[/eluser]
Thanks all,
it works now. Here is what I did :
JQuery file :
$("#loginButton").click(function() {
$.post('/login/logoutUser',
function(data) {
$.post('/login/validateUser',
{ Email: $("#email").val(),
Password: $("#password").val()},
function(data){
location.reload(true);
});
});

});

$("#logoutButton").click(function() {

$.post('/login/logoutUser',
function(data){
location.reload(true);
}
);
});

Basically call the logout function which will destroy the session. Then call the login function after reloading.

Controller :
function validateUser()
{
$email = $this->input->post('Email');
$password = $this->input->post('Password');
$isAuthenticUser = $this->Login_model->validateUser($email, $password);
}

function logoutUser()
{
// Logout the user. Unset the session user name and the rest of the data
$this->Login_model->destroyUserSession();
}

and finally
Model :
function validateUser($email, $password)
{
$results = $this->db->get_where('Users', array('Email' => $email, 'Password' => md5($password)));
if ($results->num_rows()> 0)
{
// Set the username in the session
$this->Login_model->setSessionUser($email);
}
}

function setSessionUser($email)
{
$userRow = $this->db->get_where('Users',array('Email' => $email))->result();

$this->session->set_userdata("UserName", $userRow[0]->FirstName);
$this->session->set_userdata("UserID", $userRow[0]->UserID);
$this->session->set_userdata("LoggedIn", TRUE);
}

function destroyUserSession()
{
if ($this->session->userdata('HasOrdered') || $this->session->userdata('LoggedIn'))
{
$this->session->sess_destroy();
redirect('/Login/logoutUser');
}
}
Have tested it on localhost and is fast enough. On server - don't know.


how to destroy a session and immediately create a new one? - El Forum - 04-20-2010

[eluser]WanWizard[/eluser]
You shouldn't use session_destroy() as a means of logging a user out. The user (the fysical one) still has a browser session with your site.

You should store a token in the session record to indicate that a user is logged in. This token should allow you to locate and retrieve the user record to figure out who is logged in. When the user logs out, simply reset the token to a 'guest user', no need to destroy the session (and lose all other values you would like to store in it).