14

when I update data in the User model, the Auth data is not updated.

How can I "refresh" the data which is returned by $this->Auth->user() when I am updating user model ?

and I don't want to use

$this->Auth->login($data);

after updating my user table

AnNaMaLaI
  • 3,966
  • 8
  • 50
  • 91

7 Answers7

25

I tried the following line. Its works well form me After modify the user data i written the following line

 $this->Session->write('Auth', $this->User->read(null, $this->Auth->User('id')));
AnNaMaLaI
  • 3,966
  • 8
  • 50
  • 91
  • 1
    You should not try to work around the Auth Component. If the session keys in there would be changed, you solution would immediately. – func0der Jun 13 '16 at 11:21
  • Down-vote because the correct way to do this using something like: `$this->Auth->login($newUserData);` See func0der's answer. – Tomas Gonzalez Jun 19 '16 at 03:50
  • Its some thing like Again need to authenticate the user, already the user is logged in So is this is the recommended way please let me know @deceze [~deceze] – AnNaMaLaI Jul 26 '16 at 02:40
8

Write the updated data to the Session eg:

$this->Session->write('Auth.User', $data);

Before CakePHP 2.x you can't do this in the model without break the framework design.

With CakePHP 2.x you can load the Session Component from models and update it.

  • 1
    I would like to get a comment from the user that down voted this. Why not provide any feedback. – Everton Yoshitani Nov 19 '12 at 04:23
  • I did not do it, but it is the same answer, I have given to @Annamalai.Somasundaram here: http://stackoverflow.com/questions/13440820/cakephp-2-0-how-to-update-auth-data/13443607#comment63042801_13559136 – func0der Jun 13 '16 at 11:22
5

evert0ns answer is right. But you should use AuthComponent::login(), because the data is saved within the AuthComponent as well and is not fetched from the session every time.

I had the problem just a couple of days ago.

// AppController.php
/**
 * Renews current user data, e.g. in case of an email address change while being logged in.
 *
 * @param array $newUserData
 * @return void
 */
    protected function renewUserSession($newUserData){
            if(!isset($newUserData) || empty($newUserData)){
                    return;
            }

            // We need to fetch the current user data so custom indexes are copied
            $currentUserData = $this->Auth->user();
            if(!isset($currentUserData) || empty($currentUserData)){
                    return;
            }

            // Merge old with new data
            $newUserData = array_merge($currentUserData, $newUserData);

            // Login with new data
            $this->Auth->login($newUserData);
    }

Source: my paste

Put this in your AppController. The method is specialized to merge the current and the new user data to keep existing custom indexes that you may have provided. I needed this, but you can leave it out though. Give the updated user data as a parameter to the method. Not in model find form. E.g.:

$data = array(
    'User' => array(
        'username' => 'bla',
        'passwort' => 'fu',
        'email' => 'hu@bar.com'
    )
);

// Wrong
$this->renewUserSession($data);

// Right
$this->renewUserSession($data['User']);
func0der
  • 1,997
  • 1
  • 15
  • 26
0

I solved this problem using afterSave function in User Model. It's working fine if we update user model from any area. My code was as below :

class User extends AppModel {
    ... ... ...
    public function afterSave($created, $options = array()){
        parent::afterSave($created,$options);

        //updating authentication session
        App::uses('CakeSession', 'Model/Datasource');
        CakeSession::write('Auth',$this->findById(AuthComponent::user('id')));

        return true;
    }
    ... ... ...
}
monsur.hoq
  • 1,039
  • 15
  • 23
0

I think func0der's answer is good, but it may be improved:

protected function renewLogin() {
    if(!empty($this->Auth->user())) {
        $this->loadModel('User');
        $this->User->contain(false);
        $user = $this->User->read(null, $this->Auth->user('id'))['User'];
        unset($user['password']);
        $this->Auth->login($user);
    }
}

You can add this to your AppController.php and use it from any controller after modifying the logged in user.

I believe it's much cleaner and even though it implies access to the database, I think it's not going to be executed often enough to be an issue.

You should ALWAYS try to do things the "Cake" way. And avoid shortcuts like editing a session variable. It'll make things easier for you on the long run.

Please comment and add your opinions :)

Tomas Gonzalez
  • 999
  • 14
  • 30
0

I think that the simpler way to do this is:

$user = $this->Auth->user();
$user['attribute'] = $newValue;
$this->Auth->setUser($user);
0

CakePHP 4 answer: -

$this->Authentication->getResult()->getData()->offsetSet('fullname', $user->fullname);

Where fullname is to be replaced by the user entity's field-name you have changed.

There may be a better way, but this is what I found after a lot of playing (and at this moment CakePHP 4 API has yet to be published https://api.cakephp.org/4.0/)

Jonathan
  • 748
  • 1
  • 10
  • 17