The principle of automatic login is very simple. Mainly achieved by using cookies
When logging in for the first time, if the login is successful and automatic login next time is selected, the user's authentication information will be saved in the cookie, and the cookie's validity period is 1 years or months.
The next time you log in, first determine whether the user's information is stored in the cookie. If so, use the user information stored in the cookie to log in.
Configure the User component
First set the user component in the components of the configuration file
'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ],
We see that enableAutoLogin is used To determine whether to enable the automatic login function, this has nothing to do with the next automatic login on the interface.
Only when enableAutoLogin is true, if you choose to log in automatically next time, the user information will be stored in a cookie and the validity period of the cookie will be set to 3600*24 *30 seconds for next login
Now let’s take a look at how it is implemented in Yii.
1. Save cookies when logging in for the first time
1. Login login function
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, and then execute the switchIdentity method to set the authentication information.
2. SwitchIdentity sets authentication 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.
This method mainly has three functions
① Set the validity period of the session
② If the validity period of the cookie is greater than 0 and automatic login is allowed, then save the user's authentication information to
in cookie ③ If automatic login is allowed, delete the cookie information. This is called when exiting. 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()<br/>$identity->getAuthKey()<br/>$duration
getId() and getAuthKey() are in IdentityInterfaceIn the interface. We also know that when setting up the User component, the User Model must implement the IdentityInterface interface. Therefore, you can get the first two values in the User Model, and the third value is the validity period of the cookie.
2. Automatically log in from cookie
From the above we know that the user’s authentication information has been stored in the cookie, so next time Just get the information directly from the cookie and set it.
1. AccessControl user access control
Yii provides AccessControl to determine whether the user is logged in. With this, there is no need to judge again in each action
public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'only' => ['logout'], 'rules' => [ [ 'actions' => ['logout'], 'allow' => true, 'roles' => ['@'], ], ], ], ]; }
2. getIsGuest and getIdentity determine whether to authenticate the user
isGuest is the most important attribute in the automatic login process.
In the above AccessControl access control, use the IsGuest attribute to determine whether it is an authenticated user, and then call getIdentity in the getIsGuest method Get the user information. If it is not empty, it means that it is an authenticated user, otherwise it is a 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 Regenerates 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->authTimeoutParam); 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(); } } }
Pass this part first Session is used to determine the user, because the user already exists in the session after logging in. Then determine if it is an automatic login, then log in through the cookie information.
4. Log in through the saved cookie information loginByCookie
##
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__); } } } }
$data = json_decode($value, true);Deserialize into an array.
findIdentity and validateAuthKey must be implemented in the User Model.
After logging in, you can also reset the validity period of the cookie, so that it will be valid all the time.$this->switchIdentity($identity, $this->autoRenewCookie ? $duration : 0);
3. 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)); } }
The above is the detailed content of Implementation method of automatic login and login and exit functions of Yii2 framework. For more information, please follow other related articles on the PHP Chinese website!