对于yii2中用户登录,我们可在user组件中设置session的超时时间,另外我们在session中设置session的超时时间,他们的关系是如何呢?
FancyEcommcerce原文链接为:Yii2 User cookie 登录原理 2
下面是他们的配置: session组件的配置:
'session' => [/*** use mongodb for session.*//*'class' => 'yii\mongodb\Session','db' => 'mongodb','sessionCollection' => 'session',*/'class' => 'yii\redis\Session','timeout' => 5,],
User组件的配置:
'user' => ['class' => 'fecshop\yii\web\User','identityClass' => 'fecshop\models\mysqldb\Customer',# 是否cookie 登录。/*** @var boolean whether to enable cookie-based login. Defaults to false.* Note that this property will be ignored if [[enableSession]] is false.*/'enableAutoLogin' => false,'authTimeout' => 86400,],
当session的超时时间为5秒,user的enableAutoLogin设置为false(不使用cookie,而使用session的验证登录方式),超时时间为86400秒,通过结果验证发现,5秒后在刷新页面,发现登录状态失效了,需要重新登录
让把session的超时时间设置为86400,user中的authTimeout设置为5秒,通过结果验证发现,5秒后在刷新页面,发现登录状态失效了,需要重新登录。
结果说明:User 组件,在enableAutoLogin设置为false的情况下(不使用cookie,而使用session的验证登录方式),取的是他们的最小的那个值,原因如下:
public function login(IdentityInterface $identity, $duration = 0){if ($this->beforeLogin($identity, false, $duration)) {$this->switchIdentity($identity, $duration);....
public function switchIdentity($identity, $duration = 0){.....if ($identity) {$session->set($this->idParam, $identity->getId());if ($this->authTimeout !== null) {$session->set($this->authTimeoutParam, time() + $this->authTimeout);}if ($this->absoluteAuthTimeout !== null) {$session->set($this->absoluteAuthTimeoutParam, time() + $this->absoluteAuthTimeout);}if ($duration > 0 && $this->enableAutoLogin) {$this->sendIdentityCookie($identity, $duration);}}}
identity的id保存一个cookie,相对当前超时时间保存到一个cookie,绝对超时时间保存一个cookie,一共三个cookie,他们的失效时间为session的配置中的失效时间,因此,如果session组件中配置的时间到期,就无法取出来值,
protected function renewAuthStatus(){$session = Yii::$app->getSession();$id = $session->getHasSessionId() || $session->getIsActive() ? $session->get($this->idParam) : null;if ($id === null) {$identity = null;} else {/* @var $class IdentityInterface */$class = $this->identityClass;$identity = $class::findIdentity($id);}
上面代码取出来的$id为空,因此session的超时值首先决定一个大范围,
然后user组件在这个范围内设置用户登录状态的超时时间,如果这个值超出session设置的范围,则session的超时值决定登录状态的超时时间。
另外,session的超时时间,默认为相对超时时间,譬如:你设置的为10秒超时,但是你间隔9秒刷新一次,登录状态会一直保持,如果通过配置更改为绝对超时时间,譬如设置绝对绝对超时时间为20秒,那么9秒刷新一次页面,20秒后,登录状态为失效。
if ($this->authTimeout !== null) {$session->set($this->authTimeoutParam, time() + $this->authTimeout);}if ($this->absoluteAuthTimeout !== null) {$session->set($this->absoluteAuthTimeoutParam, time() + $this->absoluteAuthTimeout);}if ($duration > 0 && $this->enableAutoLogin) {$this->sendIdentityCookie($identity, $duration);}
if ($identity !== null && ($this->authTimeout !== null || $this->absoluteAuthTimeout !== null)) {$expire = $this->authTimeout !== null ? $session->get($this->authTimeoutParam) : null;$expireAbsolute = $this->absoluteAuthTimeout !== null ? $session->get($this->absoluteAuthTimeoutParam) : null;if ($expire !== null && $expire < time() || $expireAbsolute !== null && $expireAbsolute < time()) {$this->logout(false);} elseif ($this->authTimeout !== null) {$session->set($this->authTimeoutParam, time() + $this->authTimeout);}}
通过上面的代码可以看出,绝对超时时间设置后,如果相对时间不失效,绝对时间失效,那么最终的结果是登录状态失效。
如果enableAutoLogin后,如果登录状态判断失效后,可以通过cookie重新恢复session登录状态,如果登录状态没有失效,cookie的失效时间会更新,也就是当前时间+失效时间为cookie的当前失效时间。
最后,需要说明的是,cookie的登录状态的保持的原理为:
if ($this->enableAutoLogin) {if ($this->getIsGuest()) {$this->loginByCookie();} elseif ($this->autoRenewCookie) {$this->renewIdentityCookie();}}
当session失效后,如果cookie开启就会通过cookie获取当前用户信息,最终的登录状态,还是通过session来体现,cookie的作用是在session失效,但是cookie没有实现的情况下起作用,恢复session的登录状态。