Home  >  Article  >  Backend Development  >  Implementation method of automatic login and login and exit functions of Yii2 framework

Implementation method of automatic login and login and exit functions of Yii2 framework

黄舟
黄舟Original
2017-10-25 09:02:191998browse

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()
$identity->getAuthKey()
$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__);
    }
   }
  }
}

Read the cookie value first, and then

$data = json_decode($value, true);Deserialize into an array.

From the above code, we can know that in order to achieve automatic login, these three values ​​​​must have values. In addition, the two methods

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));
  }
}

Exit At this time, first set the current authentication to null, and then determine if it is an automatic login function and then delete the relevant cookie information.

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn