I am manually modifying some key of Auth session in beforeFilter of AppController.php by this code
public function beforeFilter(Event $event){
//$companyId = $this->Companies->find(.........
$this->request->session()->write('Auth.User.company_id', $companyId);
}
And in various actions of different controller i'm trying to get that stored companyid in session by following way
public function add(){
$companyId = $this->Auth->user('company_id');
debug($companyId); die;
}
When i see the value of $companyId, it is showing older value not updated one in beforeFilter method of AppController. However if i refresh the page and donot modify session again i will get updated $companyId value.
So my question is how can i update the value of Auth session data so that i can get updated value with $this->Auth->user('company_id') code in different places in same request?
The session storage used by the authentication component uses a buffering mechanism, ie the value from the session is usually only read once per request (unless it is being deleted/emptied).
https://github.com/cakephp/cakephp/blob/3.2.8/src/Auth/Storage/SessionStorage.php#L81-L83
So either read the value directly from the session in your controller action, or do not write to the session directly, but to the session storage, something along the lines of
$user = $this->Auth->user();
if (is_array($user) && $user) {
$user['company_id'] = $companyId;
$this->Auth->setUser($user);
}
Related
I want to set global session variables where the values are retrieved from the database, in Phalcon upon entry to the site (ie. get site settings). What would be the best way to achieve this so this data is retrieved only once and remains in session accessible to views.
Thanks
Need start the session the first time when some component request the session service.
$di->setShared(
"session",
function () {
$session = new Session();
$session->start();
return $session;
}
);
Manipulations:
1) Set a session variable
$this->session->set("user-name", "Michael");
2) Check if the variable is defined and get its value
if ($this->session->has("user-name")) {
$name = $this->session->get("user-name");
}
I do have a UserController and User Model in my Laravel 5 source.
Also there is one AuthController is also Present (shipped prebuilt with laravel source).
I would like to query data from db in my blades making use of Eloquent Models.
However, Neither in my User Model (Eloquent ) nor in any of the controller, the user() method is defined. even then, I could use it in my blade by accessing it from Auth class. why?
For example,
in my blade, {{ Auth::user()->fname }} works. it retrieve the data fnamefrom my users table and echo it.
What is the logic behind it, and can i emulate the same for other db tables such as tasks?
Whenever you do it automatically or manually some like this
if (Auth::attempt(['email' => $email, 'password' => $password]))
{
}
The selected User's Data will be stored in the storage/framework/sessions
It will have data something like
a:4:{s:6:"_token";s:40:"PEKGoLhoXMl1rUDNNq2besE1iSTtSKylFFIhuoZu";s:9:"_previous";a:1:{s:3:"url";s:43:"http://localhost/Learnings/laravel5/laravel";}s:9:"_sf2_meta";a:3:{s:1:"u";i:1432617607;s:1:"c";i:1432617607;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
The above sessions file doesn't have any data and it will have the data such as user's id, url, token in json format.
Then whenever you call the {{ Auth::user()->fname }} Laravel recognises that you're trying to fetch the logged in user's fname then laravel will fetch the file and get the user's primary key and refer it from the user's table from your database. and you can do it for all coloumns of the users table that you have.
You can learn more about it here
This user function is defined under
vendor/laravel/framework/src/Illuminate/Auth/Guard.php
with following content :
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
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.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveById($id);
}
// 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.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
if ($user)
{
$this->updateSession($user->getAuthIdentifier());
$this->fireLoginEvent($user, true);
}
}
return $this->user = $user;
}
this Guard.php has more functions defined in it which we use every now and then without even knowing where they are coming from
It works because Laravel comes with decent authentication.
Auth is the authentication library and has plenty of features like this, check out the documentation!
On every page I see that new session is generated with null userdata
On model constructor
$this->config->set_item('sess_table_name', 'xx_sessions');
Because I want to store this session in another table because the other session table is being used for another login activity
Login function
function login($username,$password)
{
$this->db->where('login',$username);
$this->db->where('pass',$password);
$q=$this->db->get('prof');
// print $this->db->last_query();
if($this->db->count_all_results())
{
$arr=$q->row();
// creating the session
$this->session->set_userdata('login',$arr->id);
$this->session->set_userdata('prof',$arr->profile_id);
// print_r( $arr);
}
else
return FALSE;
}
This login function is on a model. After login and generating the session the page redirects to another page, on that page I see the session builds without any problem but when I move to another page the session losses along with the userdata.
I use the following function to check session data
function print_session()
{
print_r( $this->session->all_userdata());
}
Where I'm wrong ? Tank_auth library and ion_auth library works fine .. I had already used the
Put the session library name into the autoloader configuration, in application/config/autoload.php:
$autoload['libraries'] = array('session');
Then it's available automatically in each controller and everywhere in your application and you get your session data from anywhere:
$session_id = $this->session->userdata('session_id');
And if you don't want to auto load session library then you have to initialize the Session class manually in your controller constructor, use the $this->load->library function:
$this->load->library('session');
For details have a look here:http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Edit /application/config/config.php and set cookie domain variable
$config['cookie_domain'] = ".yourdomain.com";
It will work!
.yourdomain.com makes the cookie available throughout the domain and its sub-domains.
I have met same problem, and i have searched lots of pages.
I figured out that changing sess_cookie_name solves the problem(new sessions generating issue)
$config['sess_cookie_name'] = 'somenewname'
In my view i am trying to display the current logged in users information and have figured i can do this by using
echo "Welcome back " .$this->Session->read('Auth.User.username'). "
This displays the username and i can use the same approach to display the other fields in that database row, however some of the other fields can update at anytime but does not update on the users page until they logout and login again.
Is this correct way to do it? or can this be done a better way and somehow put some code in the beforeFilter() in AppController to continue to update the variables on each page load?
If the database is updated from outside CakePHP and without calling any controller action it seems the only solution for this is making a query on every loaded page to get the current value.
For this, you should use the beforeFilter method on the AppController:
function beforeFilter(){
$user = $this->User->field('name', array('User.id' => $this->Session->read('Auth.User.id')));
$this->Session->write('Auth.User', $user);
}
Otherwise, you can make use of JavaScript and AJAX to get the data from time to time.
I prefer to get the real time data instead of the session data
var $uses = array('User');
function beforeFilter(){
$id = $this->Auth->user('id'); //Using the session's user id is fine because it doesn't change/update
$user_data = $this->User->findById($id);
$user_fname = $user_data['User']['fname'];
$this->set('fname', $user_fname);
}
//In your view
echo 'Welcome Back '. $fname . '!';
What if you just made an afterSave() on the User model, and in it, set $this->Session->write('Auth.User') = $user;
This is non-tested, but seems like it should work - then your session would always be up to date on any changes.
Edit:
Per your comment, if the data is being pulled from a third-party source that you don't have access to, and you need to make sure it's updated on EVERY page load, then yes, the AppController's beforeFilter() is just fine.
If, however you only need it on certain pages, or certain elements, you can call the update then, or via a requestAction of an element.
Am using codeigniter to build an eCommerce site.
I have a method on controller where users enter their delivery information before checkout, the method saves the delivery information and creates a new session variable called "orderid" which has the value of the orderid as its value. After setting the session variable the method redirects to the checkout controller where i retrieve the "orderid" from the session to retrieve the order from the db for the user to confirm the information before paying.
The problem is, when the user is redirected to the checkout page, they dont see their delivery data.
When do this
echo $this->session->userdata('orderid');
I can see the value
But when i pass it to my method that supposed to return an array of data
$order = $this->orders->get_order($this->session->userdata('orderid'));
print_r($order);
I get an empty array array()
When the checkout page is refreshed it behaves correctly.
What could be the problem
In order for the session to work you have to add $this->load->library('session'); to your __contruct() function
public function __construct() {
parent::__contruct();
$this->load->library('session');
}
You cannot access session value like this
$order = $this->orders->get_order($this->session->userdata('orderid'));
You can use the following method it ll be work fine for you
$orderid=$this->session->userdata('orderid');
$order = $this->orders->get_order($orderid);
**please remembere load session library at constructor or in this function
$this->load->library('session');