Session pull and/or flush does not remove session data - php

I have this line of code in my login method
Session::put('msg','Welcome user');
And with a simple route a get through AJAX the value of that message and then delete it ( in theory ) (It's like a flash message):
public function getMessage( ){
$msg = Session::pull('msg','');// tried this
Session::flush();// and/or this
return $msg;
}
Still the message from session is not removed. I want it behave like a flash message . Why the value still persists if I used Session::pull() and\or Session::flush()?

laravel have already a system of session flash,to set data in session flash
Session::flash('msg', 'Event Created');
and then when you show this session a single time,it will automatically remove,you don't need to think about it
Session::get('msg')

Related

Session sends user object weirdly

I'm working on Laravel 9 and I have notices something that I've never seen before.
Basically I'm trying to make a Login system with Laravel 9 and for the next step of logging users in, I added an input to check for the user mobile phone number:
<input type="text" name="userinput" class="form-control" id="phone">
And at the Controller:
$findUser = User::where('usr_mobile_phone',$request->userinput)->first();
if($findUser){
Session::put('userData',$findUser);
return redirect()->route('auth.login.next');
}else{
return redirect()->back()->withErrors('No results!');
}
So as you can see I have send the userData object information to the Session called userData.
And then for the next Controller method that repsonses to auth.login.next route, I added this:
public function loginNext()
{
$user = Session::get('userData');
if(Session::has('nextStep') && Session::get('nextStep') == 1){
return view('frontend.auth.next', compact('user'));
}else{
abort(404);
}
}
Now here, I tried inserting all the object of user to $user variable.
So that in the next.blade.php, I can check informations like this:
#if(!empty($user->usr_password_hash))
// Show button login with password
#endif
So it work nice and clean but there is only one problem:
If I stay at the same page and update the record of returned $user manually in the phpmyadmin and set the usr_password_hash to NULL
So the record will be looked like:
Now the button must not be appeared on the page because this password field is empty. However it is still showing!
So this means that session has sent the user object for only one time and this user object is not prototyping live of the user data from the DB.
However if I dd($user) at the Controller method, I can properly get the user information:
So what's going wrong here?
If you know how to solve this issue, please let me know...

How can I persist data for a redirect with CodeIgniter?

I'm attempting to validate a users login attempt and inform them that
Their username is wrong or
their password is wrong (because I personally hate with a blind fury when a website doesn't inform me WHICH it is but that's beside the point).
I've read a lot of SO posts on this issue but the ones I've found are years old and I'm dealing with CodeIgniter 3.0.1.
This is the code that I have in place. I'm using Eclipse PDT to as my IDE and I like it quite a bit (but that's getting off track) so I've been able to step through the execution and watch as it just fails completely.
IF (!$this->User->login( //Testing shows this works fine - the SWITCH statement gets executed as it should and the BADUSERNAME case is followed through.
addslashes(strtolower($this->input->post('username', TRUE))),
addslashes($this->input->post('password', TRUE)),
$this->getIP())){
SWITCH($this->User->ID){
CASE 'BADUSERNAME':
$this->session->set_flashdata('user_msg', 'Invalid Username');
BREAK;
CASE 'BADPASSWORD':
$this->session->set_flashdata('user_msg', 'Invalid Password');
BREAK;
CASE 'ALREADYLOGGEDIN':
$this->session->set_flashdata('user_msg', 'You are logged in elsewhere.');
BREAK;
DEFAULT:
$this->session->set_flashdata('user_msg', 'Something has gone terribly wrong. Please try logging in again.');
BREAK;
}
redirect(base_url());
}
Then a bit further down I load the header, body, and footer views - The body is where the error message should be displayed but it's not..
<div id="contentarea">
<div class="container">
<?PHP
ECHO $this->session->flashdata('show_validation') ? validation_errors() : '';
$error = $this->session->flashdata('user_msg'); //This is where it's supposed to get it...
IF ($error) //And this is where it's supposed to show it...
ECHO "<div class='error'>$error</div>";
?> //But the value is wiped so it only ever grabs NULL.
I've followed the path of execution after calling the redirect after setting the flash data and I've noticed that after the redirect finishes it's chain of execution, it calls exit;.
Then everything loads again from the index.php file, and when Session finally pops up... the value 'user_msg' is nowhere to be found.
So clearly I'm doing something wrong here - what am I doing wrong here? Will the flash_data only persist until that redirect is called? Even the session_data values (calling $this->session->value = 'some arbitrary user message' fails to persist).
How can I persist the message for the next time the body element is loaded so that it can tell the user "Hey, didn't find you" or "Hey, your password wasn't right"?
EDIT 1
So it turns out I do not need to redirect for what I am doing as POSTing (submitting the user name and password) handles that for me.
I'm going to leave the question here for anyone else who may need it answered though - perhaps the answer is simply that Flash data just doesn't survive a redirect?
Flashed data is only available for the next http request, if you reload the page a second time, data is gone.
To persist data in the session, you want to set the variable in the session.
Codeigniter
Adding Session Data
Let’s say a particular user logs into your site. Once authenticated, you could add their username and e-mail address to the session, making that data globally available to you without having to run a database query when you need it.
You can simply assign data to the $_SESSION array, as with any other variable. Or as a property of $this->session.
Alternatively, the old method of assigning it as “userdata” is also available. That however passing an array containing your new data to the set_userdata() method:
$this->session->set_userdata($array);
$this->session->set_userdata('username', 'username is wrong');
in the view
$this -> session ->userdata('username');
or
$this ->session -> username;
Reference Session Library Codeigniter.
hope this help.
All you have to do is use $this->session->keep_flashdata('user_msg') with $this->session->unset_userdata('user_msg')
here is the solution (view file)
<?php
$error = $this->session->flashdata('user_msg');
if (isset($error)) {
echo '<div class="error">' . $error . '</div>';
$this->session->unset_userdata('user_msg');
}
?>
After that in your controller construct function (In that controller where you redirecting)
public function __construct() {
parent::__construct();
//.....
$this->session->keep_flashdata('user_msg');
}
I had same problem and this works. do not forget to clear cache when try or try in different browser
You can use codeigniter's flashdata to display errors separately.
This is what I usually use.
Controller:
$errors = array();
foreach ($this->input->post() as $key => $value){
$errors[$key] = form_error($key);
};
$response['errors'] = array_filter($errors);
$this->session->set_flashdata($response['errors']);
redirect('your-page', 'refresh');
And the to display the errors use
<?php echo $this->session->flashdata('field_name'); ?>

Yii 1.1 session sometimes won't store value

I'm getting a weird behavior I can't fully explain. Consider this controller code:
public function actionCreate()
{
$order = new Order();
$this->performAjaxValidation($order, null, 'order-form');
if (isset($_POST['Order'])) {
$order->attributes = $_POST['Order'];
if ($order->save()) {
Yii::app()->session['order_id'] = $order->id;
$this->redirect('confirm');
}
}
$this->render('create', array('order' => $order));
}
public function actionConfirm()
{
$order_id = Yii::app()->session['order_id'];
if(!$order_id) {
throw new CHttpException(404, 'Order not found');
}
$order = $this->loadModel($order_id);
$this->render('confirm', array('order' => $order));
}
So first I create the order, then if creation is successful, there is a redirect to the confirmation page. Order id is saved to the session so the customer can see the order they created. Why can't I make a redirect to "confirm($order_id)" page? Because 1. Order contains user submitted data and it can't be public, only user created that order can view it on the confirmation page, and 2. There is no authentication there, users are not required to log in.
The weird thing is, most of the time it works fine, but sometimes (1 time out of 5 approx) the order id is not saved in session. If the session is fresh, then it will end up showing 404. If it's not and you create several orders, it will evenually show the previous order data (next order is saved fine).
I would suggest that something is wrong with the session component itself (I'm using CDbHttpSession). But everything else (session related stuff) is working fine on the site (backend auth never fails, flash messages always show up).
Any ideas where should I look?
Okay, it appears pretty obvious now. The reason was classic session race condition: session auto start, performAjaxValidation reads session before order_id is set, then saves session without order_id after order_id is set but before actionConfirm is called. Native PHP sessions are blocking so this situation won't happen but db sessions are not.

Laravel store session in cookie

I have a website where the front page contains a search form with several fields.
When the user performs a search, I make an ajax call to a function in a controller.
Basically, when the user clicks on the submit button, I send an ajax call via post to:
Route::post('/search', 'SearchController#general');
Then, in the SearchController class, in the function general, I store the values received in a session variable which is an object:
Session::get("search")->language = Input::get("language");
Session::get("search")->category = Input::get("category");
//I'm using examples, not the real variables names
After updating the session variable, in fact, right after the code snippet shown above, I create (or override) a cookie storing the session values:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
And after that operation, I perform the search query and send the results, etc.
All that work fine, but I'm not getting back the values in the cookie. Let me explain myself.
As soon as the front page of my website is opened, I perform an action like this:
if (!Session::has("search")) {
//check for a cookie
$search = Cookie::get('mysite_search');
if($search) Session::put("search", json_decode($search));
else {
$search = new stdClass();
$search->language = "any";
$search->category = "any";
Session::put("search", $search);
}
}
That seems to be always failing if($search) is always returning false, and as a result, my session variable search has always its properties language and category populated with the value any. (Again: I'm using examples, not the real variables names).
So, I would like to know what is happening here and how I could achieve what I'm intending to do.
I tried to put Session::put("search", json_decode($search)); right after $search = Cookie::get('mysite_search'); removing all the if else block, and that throws an error (the ajax call returns an error) so the whole thing is failling at some point, when storing the object in the cookie or when retieving it.
Or could also be something else. I don't know. That's why I'm here. Thanks for reading such a long question.
Ok. This is what was going on.
The problem was this:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
Before having it that way I had this:
Cookie::forever("mysite_search", json_encode(Session::get("search")));
But for some reason, that approach with forever wasn't creating any cookie, so I swichted to queue (this is Laravel 4.2). But queue needs a third parameter with the expiration time. So, what was really going on is that the cookie was being deleted after closing the browser (I also have the session.php in app/config folder set to 'lifetime' => 0 and 'expire_on_close' => true which is exactly what I want).
In simple words, I set the expiration time to forever (5 years) this way:
Cookie::queue("mysite_search", json_encode(Session::get("search")), 2592000);
And now it seems to be working fine after testing it.

CakePHP: Check if SPECIFIC flash message is set

I have a page with several sections with forms that are submitted from the same page. The forms collapse to save space, but I want to conditionally keep them open if there is an error on submission.
In my controller, I set a specific "key" (see location_key below) for each form, which allows me to echo them in their respective locations:
In controller:
$this->Session->setFlash('You missed something...', 'element_name', array('class'=>'error'), 'location_key');
In view:
$this->Session->flash('location_key')
I'm trying to figure out how to check if $this->Session->flash('location_key') exists. If I do this it works but unsets the flash message:
if ( $this->Session->flash('location_key') ) // = TRUE
//Do something
$this->Session->flash('location_key') // = FALSE (because it just got called)
How can I test for the presence of this flash message without causing it to go away?
Figured it out! This works:
$this->Session->check('Message.location_key')
It returns true/false depending on whether there are any such flash messages set. ->read() does the same thing, but returns the flash data if there is (any and crucially, it leaves the session var so it can still be echoed later).
Flash messages are (surprise) stored in the session:
public function setFlash($message, $element = 'default', $params = array(), $key = 'flash') {
CakeSession::write('Message.' . $key, compact('message', 'element', 'params'));
}
To test for the presence of a flash message, test for the equivalent key in the session, e.g.:
if (CakeSession::check('Message.location_key')) {
...
}
Well, according to the api, the SessionHelper returns a string (with the flash message and element) when you do $this->Session->flash('location_key'), so why not store that string into a variable?
$myFlash = $this->Session->flash('location_key');
if ($myFlash)
/*etc*/
echo $myFlash;

Categories