Codeigniter session clear on login - codeigniter

I save preferences of anonymous user in sessions.The issue is that when user did login,I have to clear previous sessions and start new one(for security reasons).
It seems if I destroy session, then login function would do logout! Even though I use set_userdata after sess_destroy it cannot do login (maybe session after destruction becomes unusable).
Using unset acts only on a few specified sessions.Is there any way to clear all sessions of the user without such a problem?
public function login()
{
if($this->session->userdata('id'))
redirect($this->config->base_url());
if($_POST)
{
...
$user=...
if($user)
{
$this->session->sess_destroy();
$this->session->set_userdata('id',$user['id']);
....
}
else
{
....
}
}
$this->load->view('...');
}

Try reinitializing the session library after you run sess_destroy().
$this->session->sess_destroy();
$this->load->library('session');
$this->session->set_userdata('id',$user['id']);
Update:
It appears that CI does not have a native function to clear the session without damaging it for the rest of the script runtime.
However, searching for the root cause yielded a manual answer.
function unset_only() {
$user_data = $this->session->all_userdata();
foreach ($user_data as $key => $value) {
if ($key != 'session_id' && $key != 'ip_address' && $key != 'user_agent' && $key != 'last_activity') {
$this->session->unset_userdata($key);
}
}
}

do not use sess_destroy unless you are planning to redirect back again on the same url.
just use
$this->session->set_userdata('id','')
or you could create an array of the sessions you want to destroy and on its value just add a null sample
$test = array('session_id'=>'','session_id2'=>'');
$this->session->set_userdata($test);
this will make the session with names session_id and session_id2 NULL or FALSE
because when you called sess_destroy() it destroys all the session the app is using. even if you try to add another session after calling it it will not add since there are no active sessions and That's why it will not work. Tried it many times, it will only work if you refresh or redirect back to the controller/method so that a new session will be created. That's how session in CI works, i don't know correct me if i'm wrong.

Related

How can I persist Laravel session data using Inertia Vue?

I'm having trouble updating session values using Inertia.js. The behavior I was expecting was that the redirect to 'Home' would happen only once. Once the session gets cleared, any page reloads would go into 'Nok.' But that's not what happens. The $request->session()->forget(['ok']); is not persisted and always falls back to 'Home'. How do I get the expected behavior?
Example
public function home(Request $request)
{
$ok = $request->getSession()->get('ok', null);
if ($ok) {
$request->session()->forget(['ok']);
return Inertia::render('Home', [...]);
} else {
return Inertia::render('Nok', [...]);
}
}

Laravel Auth::User() performance

I have a question that whenever we call Auth::User() then its execute the query to fetch record or it have a saved instance?
Example 1
echo Auth::User()->name;
echo Auth::User()->email;
echo Auth::User()->phone;
Example 2
$userInfo=Auth::User();
echo $userInfo->name;
echo $userInfo->email;
echo $userInfo->phone;
Which one should be used performance wise?
Answer and example
Call to the database will be made only the first time you call Auth::user(), after that Laravel will store the user data and each call after that will get the stored instance rather then query the database again.
You can take a look at the vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php file under user() method. This is the code I copied from my current project which uses Laravel 7.x and this is the function called by Auth::user().
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if ($this->loggedOut) {
return;
}
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
if (! is_null($id) && $this->user = $this->provider->retrieveById($id)) {
$this->fireAuthenticatedEvent($this->user);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
if (is_null($this->user) && ! is_null($recaller = $this->recaller())) {
$this->user = $this->userFromRecaller($recaller);
if ($this->user) {
$this->updateSession($this->user->getAuthIdentifier());
$this->fireLoginEvent($this->user, true);
}
}
return $this->user;
}
Debugbar options
Also as the comment before me pointed out, it is good to download Debugbar for Laravel https://github.com/barryvdh/laravel-debugbar. It will enable you to take a look into queries being executed, views being rendered, requests being sent, and much more.
Other option is Laravel's native solution https://laravel.com/docs/8.x/telescope. I have never personally used it and IMO the first one is simpler to use.
Notes on good practice
Although both examples will essentially do the same thing, I think it is much better to use the second example. Not because of the performance, but rather to make your code readable in future. If you define the user only one time and assign Auth::user() result to it, in future it will be more obvious what it is, and plus, you can easily change what are you assigning to the $userInfo variable (maybe you want to get user from another guard in future, etc.) without having to change it on N places throughout the code.

fatfree sessions, different values in database and echo stmt

I have this in my beforeroute() of a controller
public function beforeroute()
{
new \DB\SQL\Session($this->db);
$mapper = new \DB\SQL\Mapper($this->db, 'users');
$auth = new \Auth($mapper, array(
'id' => 'username',
'pw' => 'password'
));
if (!$auth->login('validuser', '1234')) {
die('username or password wrong');
} else {
echo ($csrf = $this->db->exec('SELECT csrf FROM sessions')[0]['csrf']);
}
}
After I hit the page, I have different values for csrf in database and what's been echoed out on page. Why is that?
The csrf token is renewed on every request. You see different values on the page and in the database, because the value in the database was updated after your page has rendered.
To be more specific, the SQL Session handler replaces the default php session handler, and that's why the call to session_commit within the unload method https://github.com/bcosca/fatfree-core/blob/master/base.php#L1903 (is called when the framework shut down) will update your session database table with the new value.
To have a way to reuse that single csrf token for your purpose, just put it back into the session itself:
$s = new \DB\SQL\Session($f3->get('DB'));
// old value from last request
echo $f3->get('SESSION.csrf');
// remember current value for next request
$f3->set('SESSION.csrf',$s->csrf());
Maybe there`s an easier way, but I haven't figured it out yet.

Session value get deleted on page refresh in ci

I have a login function. When I login, the session gets saved. But when I refresh the page or redirect to another function, then the session (userdata) is shown blank. I have loaded the session library in autoload, but the userdata is deleted after every page refresh.
Here is my code.
public function index () {
$user = $this->input->post('user');
// after successful user checking
$this->session->set_userdata('user', $user);
// when I print session here,
print_r($this->session->all_userdata());
// session user gets print
}
But when I redirect to a function (suppose 'test'), then no any session is shown.
public function test() {
print_r($this->session->all_userdata());
die;
}
When you read the post value with $this->input->post('user'); and there isn't any post the function returns null and save this in the user value.
You have to check before setting.
if ($this->input->post('user')) {
$this->session->set_userdata('username', $this->input->post('user'));
}
I solved the problem. Actually, accidentally I had destroyed the session at the beginning of the code. So, my session was all destroyed. I removed the code and it's working fine.

How to Destroy All Session With Exceptional in Codeigniter?

In my code, I have logout function as below
function logout()
{
$this->session->sess_destroy();
// but, don't destroy this session
$this->session->userdata('admin_id');
}
How to destroy all session, except 'admin_id'?
The Session destroy in CI is performed at the next request, so you can't destroy a session and open a new session without a request in between.
But you could unset all session data except the data you like to keep and the data Codeigniter needs to keep the session. This Depends how session is configured, by default is it the User Agent, the last activity and the session ID. See CI-Session class preferences (at bottom of page)
This function deletes all session data except the admin_id
$sessionData = $this->session->all_userdata();
foreach($sessionData as $key =>$val){
if($key!='session_id'
&& $key!='last_activity'
&& $key!='ip_address'
&& $key!='user_agent'
&& $key!='admin_id'){
$this->session->unset_userdata($key);
}
}
You might want to save the admin_id temporarily and just put it back to session after you destroyed all your session vars.
$temp = $this->session->userdata('admin_id');
$this->session->sess_destroy();
$this->session->set_userdata('admin_id', $temp);
you must save some of keys in session, here is correct code.
$sess_array = $this->session->all_userdata();
foreach($sess_array as $key =>$val){
if($key!='session_id'
&& $key!='last_activity'
&& $key!='ip_address'
&& $key!='user_agent'
&& $key!='RESERVER_KEY_HERE')$this->session->unset_userdata($key);
}
This will work for you :)
$this->session->sess_destroy(); destroys the session_id and last_activity of the session. So the session no longer exist. So this wont work.
Try this:
$sess_array = $this->session->all_userdata();
foreach($sess_array as $key =>$val){
if($key!='session_id'||$key!='last_activity'||$key!='admin_id'){
$this->session->unset_userdata($key);
}
}

Resources