Browse Source

Move Identity Cookie code into separate functions

ar-bug
maine-mike 8 years ago committed by SilverFire - Dmitry Naumenko
parent
commit
7249a6c99e
  1. 5
      framework/CHANGELOG.md
  2. 72
      framework/web/User.php
  3. 6
      tests/framework/web/UserTest.php

5
framework/CHANGELOG.md

@ -6,6 +6,11 @@ Yii Framework 2 Change Log
----------------------- -----------------------
- Enh #11195: Added ability to append custom string to schema builder column definition (df2, samdark) - Enh #11195: Added ability to append custom string to schema builder column definition (df2, samdark)
- Enh #8795: Move Identity Cookie code into separate functions and cleanup invalid identity cookies
- Enh #8795: Move Identity Cookie code into separate functions and cleanup invalid identity cookies (maine-mike)
- Enh #8795 Move Identity Cookie code into separate functions and cleanup invalid identity cookies (maine-mike)
-•Enh #11195: Added ability to append custom string to schema builder column definition (df2, samdark)
- Enh #11195: Added ability to append custom string to schema builder column definition (df2, samdark)
- Enh #11490: Added `yii\data\ArrayDataProvider::$modelClass` property to specify a model used to provide column labels even when data array is empty (PowerGamer1) - Enh #11490: Added `yii\data\ArrayDataProvider::$modelClass` property to specify a model used to provide column labels even when data array is empty (PowerGamer1)
- Enh #11591: Added support for wildcards for `only` and `except` at `yii\base\ActionFilter` (klimov-paul) - Enh #11591: Added support for wildcards for `only` and `except` at `yii\base\ActionFilter` (klimov-paul)
- Bug #9950: Updated `yii\grid\DataColumn::getHeaderCellLabel()` to extract attribute label from the `filterModel` of Grid (silverfire) - Bug #9950: Updated `yii\grid\DataColumn::getHeaderCellLabel()` to extract attribute label from the `filterModel` of Grid (silverfire)

72
framework/web/User.php

@ -284,35 +284,17 @@ class User extends Component
*/ */
protected function loginByCookie() protected function loginByCookie()
{ {
$value = Yii::$app->getRequest()->getCookies()->getValue($this->identityCookie['name']); $data = $this->getIdentityAndDurationFromCookie();
if ($value === null) { if (isset($data['identity'], $data['duration'])) {
return; $identity = $data['identity'];
} $duration = $data['duration'];
$data = json_decode($value, true);
if (count($data) !== 3 || !isset($data[0], $data[1], $data[2])) {
return;
}
list ($id, $authKey, $duration) = $data;
/* @var $class IdentityInterface */
$class = $this->identityClass;
$identity = $class::findIdentity($id);
if ($identity === null) {
return;
} elseif (!$identity instanceof IdentityInterface) {
throw new InvalidValueException("$class::findIdentity() must return an object implementing IdentityInterface.");
}
if ($identity->validateAuthKey($authKey)) {
if ($this->beforeLogin($identity, true, $duration)) { if ($this->beforeLogin($identity, true, $duration)) {
$this->switchIdentity($identity, $this->autoRenewCookie ? $duration : 0); $this->switchIdentity($identity, $this->autoRenewCookie ? $duration : 0);
$id = $identity->getId();
$ip = Yii::$app->getRequest()->getUserIP(); $ip = Yii::$app->getRequest()->getUserIP();
Yii::info("User '$id' logged in from $ip via cookie.", __METHOD__); Yii::info("User '$id' logged in from $ip via cookie.", __METHOD__);
$this->afterLogin($identity, true, $duration); $this->afterLogin($identity, true, $duration);
} }
} else {
Yii::warning("Invalid auth key attempted for user '$id': $authKey", __METHOD__);
} }
} }
@ -562,6 +544,48 @@ class User extends Component
} }
/** /**
* Determines if an identity cookie has a valid format and contains a valid auth key.
* This method is used when [[enableAutoLogin]] is true.
* This method attempts to authenticate a user using the information in the identity cookie.
* @return array|null Returns an array of 'identity' and 'duration' if valid, otherwise null.
* @see loginByCookie()
*/
protected function getIdentityAndDurationFromCookie()
{
$value = Yii::$app->getRequest()->getCookies()->getValue($this->identityCookie['name']);
if ($value === null) {
return;
}
$data = json_decode($value, true);
if (count($data) == 3) {
list ($id, $authKey, $duration) = $data;
/* @var $class IdentityInterface */
$class = $this->identityClass;
$identity = $class::findIdentity($id);
if ($identity !== null) {
if (!$identity instanceof IdentityInterface) {
throw new InvalidValueException("$class::findIdentity() must return an object implementing IdentityInterface.");
} elseif (!$identity->validateAuthKey($authKey)) {
Yii::warning("Invalid auth key attempted for user '$id': $authKey", __METHOD__);
} else {
return ['identity' => $identity, 'duration' => $duration];
}
}
}
$this->removeIdentityCookie();
return;
}
/**
* Removes the identity cookie.
* This method is used when [[enableAutoLogin]] is true.
*/
protected function removeIdentityCookie()
{
Yii::$app->getResponse()->getCookies()->remove(new Cookie($this->identityCookie));
}
/**
* Switches to a new identity for the current user. * Switches to a new identity for the current user.
* *
* When [[enableSession]] is true, this method may use session and/or cookie to store the user identity information, * When [[enableSession]] is true, this method may use session and/or cookie to store the user identity information,
@ -585,7 +609,7 @@ class User extends Component
/* Ensure any existing identity cookies are removed. */ /* Ensure any existing identity cookies are removed. */
if ($this->enableAutoLogin) { if ($this->enableAutoLogin) {
Yii::$app->getResponse()->getCookies()->remove(new Cookie($this->identityCookie)); $this->removeIdentityCookie();
} }
$session = Yii::$app->getSession(); $session = Yii::$app->getSession();

6
tests/framework/web/UserTest.php

@ -122,6 +122,12 @@ class UserTest extends TestCase
$this->mockWebApplication($appConfig); $this->mockWebApplication($appConfig);
Yii::$app->session->removeAll(); Yii::$app->session->removeAll();
$cookie = new Cookie(Yii::$app->user->identityCookie);
$cookie->value = 'junk';
$cookiesMock->add($cookie);
Yii::$app->user->getIdentity();
$this->assertTrue(strlen($cookiesMock->getValue(Yii::$app->user->identityCookie['name'])) == 0);
Yii::$app->user->login(UserIdentity::findIdentity('user1'),3600); Yii::$app->user->login(UserIdentity::findIdentity('user1'),3600);
$this->assertFalse(Yii::$app->user->isGuest); $this->assertFalse(Yii::$app->user->isGuest);
$this->assertSame(Yii::$app->user->id, 'user1'); $this->assertSame(Yii::$app->user->id, 'user1');

Loading…
Cancel
Save