Fecshop 2017-01-17 17:52:00 9519次浏览 4条评论 3 1 0

对于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的登录状态。

觉得很赞
  • 评论于 2017-01-18 09:22 举报

    最后,推荐一下我的Fecshop ,开源商城,github地址:https://github.com/fancyecommerce/yii2_fecshop

    演示地址:http://fecshop.appfront.fancyecommerce.com/

    截止到2016-11-12号,产品,分类,首页,评论,用户中心,搜索,多语言,多货币 等功能已经做完,除了购物车和支付部分,其他的基本都已经完成,关注fecshop的 在等2-3个月,也就是明年2,3月份,版本已经就可以出来,2017年4,5月份在把手机web 做一下,预计到明年5月份,后台,pc前台,手机web前台 ,命令控制台 这几个入口 基本可以完善,多谢大家关注和你们的Star,谢谢,我会坚持把他写好。

    作者QQ:2358269014

    , 觉得很赞
  • 评论于 2017-01-20 08:54 举报

    identity的id保存一个cookie,相对当前超时时间保存到一个cookie,绝对超时时间保存一个cookie,一共三个cookie,他们的失效时间为session的配置中的失效时间,因此,如果session组件中配置的时间到期,就无法取出来值,

    改为:

    identity的id保存一个session,相对当前超时时间保存到一个session,绝对超时时间保存一个session,一共三个session,他们的失效时间为session的配置中的失效时间,因此,如果session组件中配置的时间到期,就无法取出来值,

  • 评论于 2017-01-20 08:56 举报

    最后一句:

    当session失效后,如果cookie开启就会通过cookie获取当前用户信息,最终的登录状态,还是通过session来体现,cookie的作用是在session失效,但是cookie没有实现的情况下起作用,恢复session的登录状态。

    改为

    当session失效后,如果cookie开启就会通过cookie获取当前用户信息,最终的登录状态,还是通过session来体现,cookie的作用是在session失效,但是cookie没有超时的情况下起作用,恢复session的登录状态。

  • 评论于 2017-10-20 11:37 举报
    'session'      => [
                // this is the name of the session cookie used for login on the backend
                'name' => 'advanced-backend',
                'timeout' => 5,
            ], 
    

    'enableAutoLogin' => false,'authTimeout' => 28800,
    发现5秒不会退出(Windows),当session的timeout不设置的话,liunx环境用户还没到28800秒就提前退出了。怎么理解?

您需要登录后才可以评论。登录 | 立即注册