Browse Source

Fix #19067: Fix constant session regeneration (#19113)

* Fix constant session regeneration
* Add tests for session ID, always regenerating session ID for switching identity
tags/2.0.44
Bizley 3 years ago committed by GitHub
parent
commit
12763a146e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      framework/web/User.php
  2. 49
      tests/framework/web/UserTest.php

9
framework/web/User.php

@ -655,9 +655,7 @@ class User extends Component
}
$session = Yii::$app->getSession();
if (!YII_ENV_TEST) {
$session->regenerateID(true);
}
$session->remove($this->idParam);
$session->remove($this->authTimeoutParam);
$session->remove($this->authKeyParam);
@ -698,6 +696,9 @@ class User extends Component
/* @var $class IdentityInterface */
$class = $this->identityClass;
$identity = $class::findIdentity($id);
if ($identity === null) {
$this->switchIdentity(null);
}
}
if ($identity !== null) {
@ -728,10 +729,6 @@ class User extends Component
$this->renewIdentityCookie();
}
}
if ($this->getIdentity(false) === null) {
$this->switchIdentity(null);
}
}
/**

49
tests/framework/web/UserTest.php

@ -169,6 +169,7 @@ class UserTest extends TestCase
];
$this->mockWebApplication($appConfig);
$id1 = Yii::$app->session->id;
Yii::$app->session->removeAll();
$cookie = new Cookie(Yii::$app->user->identityCookie);
@ -176,16 +177,21 @@ class UserTest extends TestCase
$cookiesMock->add($cookie);
Yii::$app->user->getIdentity();
$this->assertEquals(strlen($cookiesMock->getValue(Yii::$app->user->identityCookie['name'])), 0);
$this->assertSame($id1, Yii::$app->session->id);
Yii::$app->user->login(UserIdentity::findIdentity('user1'), 3600);
$this->assertFalse(Yii::$app->user->isGuest);
$this->assertSame(Yii::$app->user->id, 'user1');
$this->assertNotEquals(strlen($cookiesMock->getValue(Yii::$app->user->identityCookie['name'])), 0);
$id2 = Yii::$app->session->id;
$this->assertNotSame($id1, $id2);
Yii::$app->user->login(UserIdentity::findIdentity('user2'), 0);
$this->assertFalse(Yii::$app->user->isGuest);
$this->assertSame(Yii::$app->user->id, 'user2');
$this->assertEquals(strlen($cookiesMock->getValue(Yii::$app->user->identityCookie['name'])), 0);
$id3 = Yii::$app->session->id;
$this->assertNotSame($id2, $id3);
}
/**
@ -225,7 +231,7 @@ class UserTest extends TestCase
],
];
$this->mockWebApplication($appConfig);
$id = Yii::$app->session->id;
$user = Yii::$app->user;
@ -234,6 +240,7 @@ class UserTest extends TestCase
$user->loginRequired();
$this->assertEquals('normal', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
@ -242,12 +249,13 @@ class UserTest extends TestCase
$user->loginRequired();
$this->assertEquals(Yii::$app->getHomeUrl(), $user->getReturnUrl());
// AJAX requests don't update returnUrl but they do cause redirection.
// AJAX requests don't update returnUrl, but they do cause redirection.
$this->assertTrue(Yii::$app->response->getIsRedirection());
$user->loginRequired(false);
$this->assertEquals('ajax', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
Yii::$app->request->setUrl('json-only');
@ -255,6 +263,7 @@ class UserTest extends TestCase
$user->loginRequired(true, false);
$this->assertEquals('json-only', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
Yii::$app->request->setUrl('json-only');
@ -262,6 +271,7 @@ class UserTest extends TestCase
$user->loginRequired(true, false);
$this->assertEquals('json-only', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
Yii::$app->request->setUrl('accept-all');
@ -269,6 +279,7 @@ class UserTest extends TestCase
$user->loginRequired();
$this->assertEquals('accept-all', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
Yii::$app->request->setUrl('json-and-accept-all');
@ -278,6 +289,7 @@ class UserTest extends TestCase
} catch (ForbiddenHttpException $e) {
}
$this->assertFalse(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
Yii::$app->request->setUrl('accept-html-json');
@ -285,6 +297,7 @@ class UserTest extends TestCase
$user->loginRequired();
$this->assertEquals('accept-html-json', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
Yii::$app->request->setUrl('accept-html-json');
@ -292,6 +305,7 @@ class UserTest extends TestCase
$user->loginRequired();
$this->assertEquals('accept-html-json', $user->getReturnUrl());
$this->assertTrue(Yii::$app->response->getIsRedirection());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
$_SERVER['REQUEST_METHOD'] = 'POST';
@ -299,6 +313,7 @@ class UserTest extends TestCase
Yii::$app->getSession()->set($user->returnUrlParam, null);
$user->loginRequired();
$this->assertNull(Yii::$app->getSession()->get($user->returnUrlParam));
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
$_SERVER['REQUEST_METHOD'] = 'GET';
@ -306,6 +321,7 @@ class UserTest extends TestCase
Yii::$app->getSession()->set($user->returnUrlParam, null);
$user->loginRequired();
$this->assertEquals('set-return-url-on-get-request', Yii::$app->getSession()->get($user->returnUrlParam));
$this->assertSame($id, Yii::$app->session->id);
// Confirm that returnUrl is not set.
$this->reset();
@ -316,11 +332,13 @@ class UserTest extends TestCase
} catch (ForbiddenHttpException $e) {
}
$this->assertNotEquals('json-only', $user->getReturnUrl());
$this->assertSame($id, Yii::$app->session->id);
$this->reset();
$_SERVER['HTTP_ACCEPT'] = 'text/json;q=0.1';
$this->expectException('yii\\web\\ForbiddenHttpException');
$user->loginRequired();
$this->assertSame($id, Yii::$app->session->id);
}
public function testLoginRequiredException1()
@ -482,8 +500,10 @@ class UserTest extends TestCase
$this->mockWebApplication($appConfig);
Yii::$app->session->set('__id', 'user1');
$id = Yii::$app->session->id;
$this->assertNotNull(Yii::$app->user->getIdentity());
$this->assertSame($id, Yii::$app->session->id);
}
public function testSessionAuthWithInvalidKey()
@ -497,12 +517,13 @@ class UserTest extends TestCase
];
$this->mockWebApplication($appConfig);
$id = Yii::$app->session->id;
Yii::$app->session->set('__id', 'user1');
Yii::$app->session->set('__authKey', 'invalid');
$this->assertNull(Yii::$app->user->getIdentity());
$this->assertSame($id, Yii::$app->session->id);
}
public function testSessionAuthWithValidKey()
@ -516,11 +537,33 @@ class UserTest extends TestCase
];
$this->mockWebApplication($appConfig);
$id = Yii::$app->session->id;
Yii::$app->session->set('__id', 'user1');
Yii::$app->session->set('__authKey', 'ABCD1234');
$this->assertNotNull(Yii::$app->user->getIdentity());
$this->assertSame($id, Yii::$app->session->id);
}
public function testSessionAuthWhenIdentityReturnsNull()
{
$appConfig = [
'components' => [
'user' => [
'identityClass' => UserIdentity::className(),
],
],
];
$this->mockWebApplication($appConfig);
$id = Yii::$app->session->id;
Yii::$app->session->set('__id', 'user999999');
Yii::$app->session->set('__authKey', 'ABCD1234');
$this->assertNull(Yii::$app->user->getIdentity());
$this->assertNotSame($id, Yii::$app->session->id);
}
}

Loading…
Cancel
Save