The principle of automatic login is simple. The main thing is to use cookies to achieve
On the first login, if the login is successful and the next automatic login is selected, the user's authentication information will be saved to the cookie and the cookie is valid for 1 years or several months.
The next time you log in to determine whether the cookie stores the user's information, if there is a cookie stored in the user information to log in,
Configuring the User Component
First set up the user component in the configuration file components
' User ' = [' identityclass ' = ' app\models\user ', ' enableautologin ' = true,],
We see enableautologin is used to determine whether to enable the automatic login function, this and the interface on the next automatic login Independent.
Only if Enableautologin is true, if the next automatic login is selected, the user information is stored in the cookie and the cookie is set to be valid for 3600*24*30 seconds for the next logon
Now let's look at how it's implemented in Yii.
First Login and save cookies
1 login Function of Login
Public Function Login ($identity, $duration = 0) { if ($this->beforelogin ($identity, False, $duration)) { $ This->switchidentity ($identity, $duration); $id = $identity->getid (); $ip = Yii:: $app->getrequest ()->getuserip (); Yii::info ("User ' $id ' logged in from $ip with duration $duration.", __method__); $this->afterlogin ($identity, False, $duration); } Return! $this->getisguest ();}
Here, simply log in, then execute the switchidentity method and set the authentication information.
2, Switchidentity set up certification information
Public Function switchidentity ($identity, $duration = 0) { $session = Yii:: $app->getsession (); if (! Yii_env_test) { $session->regenerateid (True); } $this->setidentity ($identity); $session->remove ($this->idparam); $session->remove ($this->authtimeoutparam); if ($identity instanceof identityinterface) { $session->set ($this->idparam, $identity->getid ()); if ($this->authtimeout!== null) { $session->set ($this->authtimeoutparam, Time () + $this authtimeout); } if ($duration > 0 && $this->enableautologin) { $this->sendidentitycookie ($identity, $duration); } } ElseIf ($this->enableautologin) { Yii:: $app->getresponse ()->getcookies ()->remove (New Cookie ($ This->identitycookie));} }
This method is more important and needs to be called when exiting.
There are three main functions of this method
① setting the duration of the session
② If the cookie is valid for more than 0 and allows automatic login, the user's authentication information is saved to the cookie
③ If you allow automatic login, delete cookie information. This is called when the exit is used. The $identity passed in when exiting is null
protected function Sendidentitycookie ($identity, $duration) { $cookie = new Cookie ($this->identitycookie); $cookie->value = Json_encode ([ $identity->getid (), $identity->getauthkey (), $duration, ]); $cookie->expire = time () + $duration; Yii:: $app->getresponse ()->getcookies ()->add ($cookie);}
The user information stored in the cookie contains three values:
$identity->getId()
$identity->getAuthKey()
$duration
GetId () and Getauthkey () are in the identityinterface interface. We also know that the user model must implement the Identityinterface interface when setting up the user component. Therefore, the first two values can be obtained in the user model, and the third value is the expiration date of the cookie.
Second, automatically log in from the cookie
From the above we know that the user's authentication information has been stored in the cookie, then the next time directly from the cookie to take information and then set it up.
1. AccessControl User Access control
Yii provides accesscontrol to determine if a user is logged in, and with this it does not need to be judged in every action.
Public Function Behaviors () { return [ ' access ' + = ' class ' = Accesscontrol::classname (), ' Only ' + ' = [' logout '], ' rules ' and ' [ ' actions ' = ' = ' logout '], ' Allow ' and ' = True ' Roles ' = = [' @ '],], [],] , ];
2, Getisguest, getidentity judge whether to authenticate users
Isguest is the most important attribute in the automatic login process.
In the above AccessControl access control through the Isguest property to determine whether it is authenticated users, and then in the Getisguest method is called getidentity to obtain user information , if not empty the description is authenticated users, otherwise is the visitor (not logged in).
Public Function getisguest ($checkSession = True) { return $this->getidentity ($checkSession) = = = NULL;} Public Function getidentity ($checkSession = True) { if ($this->_identity = = = False) { if ($checkSession) { $this->renewauthstatus (); } else { return null; } } return $this->_identity;}
3, Renewauthstatus re-generate user authentication information
protected function Renewauthstatus () {$session = Yii:: $app->getsession (); $id = $session->gethassessionid () | | $session->getisactive ()? $session->get ($this->idparam): null; if ($id = = = null) {$identity = null; } else {/** @var identityinterface $class */$class = $this->identityclass; $identity = $class:: findidentity ($id); } $this->setidentity ($identity); if ($this->authtimeout!== null && $identity!== null) {$expire = $session->get ($this->authtimeoutpara m); if ($expire!== null && $expire < time ()) {$this->logout (false); } else {$session->set ($this->authtimeoutparam, Time () + $this->authtimeout); }} if ($this->enableautologin) {if ($this->getisguest ()) {$this->loginbycookie (); } elseif ($this->autorenewcookie) {$this->renewidentitycookie (); } }}
This part of the first through the session to determine the user, because the user login has already existed in the session. Then, if you are automatically logged in, you can log in using cookie information.
4. Log in Loginbycookie by storing cookie information
protected function Loginbycookie () {$name = $this->identitycookie[' name ']; $value = Yii:: $app->getrequest ()->getcookies ()->getvalue ($name); if ($value!== null) {$data = Json_decode ($value, true); if (count ($data) = = = 3 && isset ($data [0], $data [1], $data [2])) {list ($id, $authKey, $duration) = $data; /** @var identityinterface $class */$class = $this->identityclass; $identity = $class:: findidentity ($id); if ($identity!== null && $identity->validateauthkey ($authKey)) {if ($this->beforelogin ($identity, True , $duration)) {$this->switchidentity ($identity, $this->autorenewcookie? $duration: 0); $ip = Yii:: $app->getrequest ()->getuserip (); Yii::info ("User ' $id ' logged in from $ip via cookie.", __method__); $this->afterlogin ($identity, True, $duration); }} elseif ($identity!== null) {yii::warning ("Invalid Auth key attempted for user ' $id ': $authKey", __method__); } } }}
The cookie value is read first and then $data = json_decode($value, true);
deserialized into an array.
This code from the above can know that to achieve automatic login, these three values must have a value. In addition, the findidentityandValidateauthkey methods must be implemented in the user model.
Once the login is complete, you can also reset the cookie expiration date so that it works together.
$this->switchidentity ($identity, $this->autorenewcookie? $duration: 0);
Third, exit logout
Public Function Logout ($destroySession = true) {$identity = $this->getidentity (); if ($identity!== null && $this->beforelogout ($identity)) {$this->switchidentity (null); $id = $identity->getid (); $ip = Yii:: $app->getrequest ()->getuserip (); Yii::info ("User ' $id ' logged out from $ip.", __method__); if ($destroySession) {Yii:: $app->getsession ()->destroy (); } $this->afterlogout ($identity); } return $this->getisguest ();} Public Function switchidentity ($identity, $duration = 0) {$session = Yii:: $app->getsession (); if (! Yii_env_test) {$session->regenerateid (true); } $this->setidentity ($identity); $session->remove ($this->idparam); $session->remove ($this->authtimeoutparam); if ($identity instanceof identityinterface) {$session->set ($this->idparam, $identity->getid ()); if ($this->authtimeout!== null) {$session->set ($this->authtimeoutparam, Time () + $this->authtimeout); }if ($duration > 0 && $this->enableautologin) {$this->sendidentitycookie ($identity, $duration); }} elseif ($this->enableautologin) {Yii:: $app->getresponse ()->getcookies ()->remove (New Cookie ($this- >identitycookie)); }}
When exiting, set the current authentication to null, and then determine if the automatic login function will delete the relevant cookie information.