Yii2 User cookie 登录原理_TERRY
来源:互联网 发布:手机淘宝怎么用信用卡 编辑:程序博客网 时间:2024/05/22 06:54
本文是在session登录畅通无阻的前提下,首先要先搞好session登录,这个在这里不做叙述,好多session登录的文章。本文叙述cookie登录的原理和使用
FancyEcommerce原文链接:Yii2 User cookie 登录原理
1.具体实现:
1.1 cookie登录配置config方面,配置好的代码如下:
'components' => [ 'user' => [ 'identityClass' => 'fecshop\models\mysqldb\Customer', 'enableAutoLogin' => true, 'authTimeout' => 3600, ], ],
enableAutoLogin设置为true,就会使用cookie登录,如果设置了enableAutoLogin,那么下面的超时时间authTimeout就会无效,因为这个参数是session的超时时间,不过,我们可以在登录的时候,超时时间也从这个配置参数读取,譬如下面的函数参数$duration,可以从这里读取,如果这样,就会有效。
$duration = \Yii::$app->user->authtimeout; \Yii::$app->user->login($this->getCustomer(), $duration);
上面的结论通过代码解释,如下:
public function login(IdentityInterface $identity, $duration = 0) { if ($this->beforeLogin($identity, false, $duration)) { $this->switchIdentity($identity, $duration); $id = $identity->getId(); $ip = Yii::$app->getRequest()->getUserIP(); if ($this->enableSession) { $log = "User '$id' logged in from $ip with duration $duration."; } else { $log = "User '$id' logged in from $ip. Session not enabled."; } Yii::info($log, __METHOD__); $this->afterLogin($identity, false, $duration); } return !$this->getIsGuest(); }
查看 $this->switchIdentity($identity, $duration);
public function switchIdentity($identity, $duration = 0) { $this->setIdentity($identity); if (!$this->enableSession) { return; } /* Ensure any existing identity cookies are removed. */ if ($this->enableAutoLogin) { $this->removeIdentityCookie(); } $session = Yii::$app->getSession(); if (!YII_ENV_TEST) { $session->regenerateID(true); } $session->remove($this->idParam); $session->remove($this->authTimeoutParam); 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); } } }
查看:$this->sendIdentityCookie($identity, $duration);
protected function sendIdentityCookie($identity, $duration) { $cookie = new Cookie($this->identityCookie); $cookie->value = json_encode([ $identity->getId(), $identity->getAuthKey(), $duration, ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $cookie->expire = time() + $duration; Yii::$app->getResponse()->getCookies()->add($cookie); }
通过一层层的函数可以看到,cookie的超时时间是从login()函数中读取出来的,
而不是从\yii\web\User的authTimeout
变量读取。最后传递给sendIdentityCookie($identity, $duration)
方法,进而设置cookie的超时时间。
另外配置中开启了enableAutoLogin,但是在调用login方法的时候没有设置超时时间变量$duration,同样不会设置cookie,进而配置 enableAutoLogin 无效,下面是代码解释:
public function switchIdentity($identity, $duration = 0){ #函数中的代码 if ($duration > 0 && $this->enableAutoLogin) { $this->sendIdentityCookie($identity, $duration); }}
可以看到,如果超时时间为0,那么不会执行设置cookie的方法
public function sendIdentityCookie($identity, $duration);
进而不会设置cookie
1.2 代码改进:
参考代码:
public function getCustomer(){ if($this->_customer === null){ $this->_customer = Customer::findByEmail($this->email); } return $this->_customer; } public function login($duration = 86400) { if ($this->validate()) { //return \Yii::$app->user->login($this->getAdminUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); return \Yii::$app->user->login($this->getCustomer(), $duration); } else { return false; } }
在上面的代码,默认cookie的过期时间为86400秒,这样默认就不会cookie超时
如果我我调用:
$model = new CustomerLogin; $model->email = $data['email']; $model->password = $data['password']; $loginStatus = $model->login(0);
由于过期时间填写为0,因此,即使在user组件中开启配置enableAutoLogin=true,
cookie也不会生效。
另外,我如果从\yii\web\User的authTimeout变量读取。来设置cookie的超时时间,也是一个不错的选择,代码如下:
public function login($duration = 0) { if(!$duration){ if(Yii::$app->user->authTimeout){ $duration = Yii::$app->user->authTimeout; } } if ($this->validate()) { //return \Yii::$app->user->login($this->getAdminUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); return \Yii::$app->user->login($this->getCustomer(), $duration); } else { return false; } }
- cookie超时时间刷新。
在默认的情况下,如果登录成功账户,每次请求访问Yii::$app->user->identity,都会刷新cookie的超时时间,设置自动更新的变量为:public $autoRenewCookie = true;
该变量默认为true,所以不需要在配置中设置这个变量,使用默认就好。
cookie超时时间刷新的原理解释,下面是详细代码:
执行Yii::$app->user->identity,对应的是下面的函数
public function getIdentity($autoRenew = true) { if ($this->_identity === false) { if ($this->enableSession && $autoRenew) { $this->_identity = null; $this->renewAuthStatus(); } else { return null; } } return $this->_identity; }
会执行renewAuthStatus()方法
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); } $this->setIdentity($identity); 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); } } if ($this->enableAutoLogin) { if ($this->getIsGuest()) { $this->loginByCookie(); } elseif ($this->autoRenewCookie) { $this->renewIdentityCookie(); } } }
如果enableAutoLogin开启,如果登录就会执行renewIdentityCookie方法。
protected function renewIdentityCookie() { $name = $this->identityCookie['name']; $value = Yii::$app->getRequest()->getCookies()->getValue($name); if ($value !== null) { $data = json_decode($value, true); if (is_array($data) && isset($data[2])) { $cookie = new Cookie($this->identityCookie); $cookie->value = $value; $cookie->expire = time() + (int) $data[2]; Yii::$app->getResponse()->getCookies()->add($cookie); } } }
该方法会重新设置超时时间,通过上面的几个函数知道了原理,那么问题来了,如果我登录了用户,超时时间设置的为10秒,我开始浏览器文章或者干其他的,每次访问间隔3秒,如果这些页面都没有执下面的行代码:Yii::$app->user->identity
那么,10秒后,用户登录状态就会被超时,需要重新登录,(有一些间接的方法也会执行上面的代码,譬如Yii::$app->user->isGuest ,就会间接调用执行Yii::$app->user->identity,这种情况下不会超时)。
public function getIsGuest() { return $this->getIdentity() === null; }
因此,如果登录状态要持久下去,那么为了保持登录状态,每个页面请求后,都需要执行Yii::$app->user->identity,然后cookie的超时时间就会更新,这样3秒请求一次,登录状态会一直保持下去。
上面是yii2 cookie使用过程中要注意的一些问题。总体来说还是不错,但在实际过程中,还需要结合一下其他,譬如cart 和customer login都使用cookie,超时时间要一致,那么,cart和customer的cookie超时时间要一致,并且,在每次调用Yii::$app->user->identity,都必须执行更新cart的cookie超时时间,因此,需要重写Yii\web\User。
下一个章节介绍实现的具体步骤。
文章来源 http://www.fancyecommerce.com/2017/01/17/yii2-user-%E7%99%BB%E5%BD%95%E5%8E%9F%E7%90%86/
- Yii2 User cookie 登录原理_TERRY
- Yii2 User 登录原理
- cookie保存user数据及cookie实现自动登录
- yii2 cookie
- yii2-user的使用
- yii2中的User类
- 如何修改yii2.0用户登录使用的user表为其它的表
- yii2.0的cookie
- Yii2.0 Cookie使用方法
- yii2.0 user功能解析
- yii2 3: 创建user数据库
- yii2登录注册
- yii2之登录表单
- yii2-用户登录验证
- Yii2 sso 登录
- yii2登录笔记
- 基于cookie-redis实现单点登录的原理浅谈
- Cookie登录
- Web Work 简介
- Python代码应该这样写
- RxJava 与 Retrofit 结合的最佳实践
- python011 -- 迭代器 生成器
- iOS 横向展示瀑布流 排列不规则长度标题的UIButton
- Yii2 User cookie 登录原理_TERRY
- 分别在Tomcat,spring初始化时注册监听器
- [LeetCode] Unique Paths
- MFC读取Excel例子(OLE/COM)
- Python之数组(array)使用方法总结与Numpy中的数组用法
- Docker学习笔记-Docker端口映射
- Linux(Ubuntu16.04)自学笔记,资源整理
- Mysql--key
- AngularJS model !