Saving Session Variables for User whenever they are authenticated

All,

I’ve been using Yii 2 over the past month and I love it! I got very adept at Yii 1 through Larry Ullman’s amazing book and I’m surprised at how quickly I could run with Yii 2. I am running into an issue that I handled in Yii 1 but I want to know if I’m using the best approach to handle it in Yii 2.

  • PROBLEM: Want to ensure that when user is authenticated, the system doesn’t just load their authentication status but also loads an aspects of a user into the session

  • SITUATION: If RememberMe is on, the system remembers that the user has been logged in even if browser is shut down and reopened. Fantastic! However, when logging back in, the user does not go through the login function which saves their timezone into the session. Boo!

  • SOLUTION: Create a BaseController that extends controller. Is user is not a guest BUT user does not have a timezone saved into their session THEN load the timezone into the session. All controllers will now extend this new BaseController

This approach works. However, is it the best approach?

Take care,

-saniko

Is there any way to save additional data into the identity?

you could store it in the db? Also, if you store it in session / cookies and it’s not set to expire then it will be there when they come back.

You can also extend identity to add more data but i think you’d be in the same boat just adding the timezone to identity.

You can always get it via js really easily


var tz = jstz.determine(); // time zone of the browser client 

tz.name(); // name of time zone eg "America/New_York"

Nice tip for the timezone data! I just realized that everything saved under the user record is available via Yii::$app->user->identity-> so I could just use Yii::$app->user->identity->timezone.

If you save it to the users table you can also do Yii::$app->user->timezone

Actually, that doesn’t work. To access items in the user record, you need to do Yii::$app->user->identity-> not Yii::$app->user->

i just looked at the docs you’re right it only works for Id/getId


Yii::$app->user->id;

and


Yii::$app->user->getId();

which just looks like it’s another way to do




Yii::$app->user->identity->id;  

If I get everything right, then you’ve got your user model which implements IdentityInterface.

And then you may (must) implement validateAuthKey() method. This method checks the user auth (compares $authKey with the stored one). This method will be called each time the user authes by rememberMe or any other method using authKey. So, if the auth is successful, you may do anything you want (set timezone or anything). The code is very simple:


    public function validateAuthKey($authKey)

    {

        if ($this->getAuthKey() === $authKey) {

            if (!$this->timezone) $this->updateAttributes(['timezone' => 'Europe/Berlin']);

            return true;

        }

        return false;

    }

I’ve got another method called validatePassword() which is executed each time the user logs in using password (login form). So, I may do anything with the model depending on the auth event (by key or by password).

There is the other approach - use events. It is much more complicated and flexible. Shortly, you create the event handler, register it and then trigger.