Yii2 User 登录原理
本文是在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。
Yii2 User 登录原理相关推荐
- 详细分析本机号码一键登录原理
详细分析本机号码一键登录原理! 很多 APP 的目前都支持「本机号码一键登录」功能.本机号码一键登录是基于运营商独有网关认证能力推出的账号认证产品.用户只需一键授权,即可实现以本机号码注册/登录,相比 ...
- YII2 实现登录时候修改最新登录时间
YII2 实现登录时候修改最新登录时间 YII2保存最新登录时间主要技巧:为 EVENT_AFTER_LOGIN 事件绑定一个方法,在方法中保存最新时间 public function login() ...
- cas跨域单点登录原理_CAS实现SSO单点登录原理
1. CAS 简介 1.1. What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...
- 聊一聊二维码扫描登录原理
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:2 个月的面试亲身经历告诉大家,如何进入大厂? 扫二维码登录现在比较常见,比如微信.支付宝等 PC 端登录,并且 ...
- CAS单点登录原理简单介绍
1. SSO简介 1.1 单点登录定义 单点登录(Single sign on),英文名称缩写SSO,SSO的意思就是在多系统的环境中,登录单方系统,就可以在不用再次登录的情况下访问相关受信任的系统. ...
- MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN
在Membership系列的最后一篇引入了ASP.NET Identity,看到大家对它还是挺感兴趣的,于是来一篇详解登录原理的文章.本文会涉及到Claims-based(基于声明)的认证,我们会详细 ...
- 二维码登录原理及生成与解析
一.前言 这几天在研究二维码的扫码登录.初来乍到,还有好多东西不懂.在网上看到有人写了一些通过QRCode或者Zxing实现二维码的生成和解码.一时兴起,决定自己亲手试一试.本人是通过QRCode实现 ...
- 微信QQ的二维码登录原理js代码解析
这篇文章主要大家详细解析了微信QQ的二维码登录原理js代码, 具有一定的参考价值,感兴趣的小伙伴们可以参考一下 在很多地方就是都出现了使用二维码登录,二维码付款,二维码账户等应用(这里的二维码种马,诈 ...
- RTX的“远程登录”原理是什么?
RTX的"远程登录"原理很简单,实际上是由腾讯公司为所有使用RTX的用户提供的一项中转运营服务. 所有开通了"远程登录"服务的RTX服务器,不需要有外部IP,不 ...
最新文章
- ICML2020 | 神经网络的图结构如何影响其预测性能?
- Outlook启动提示“找不到文件Outlook.pst文件”
- 聚类分析在用户行为中的实例_聚类分析在用户分类中的应用
- python3 Number List 元组 字典 用法区分和总结
- python文档的数据读取,把读取数据写入到新的表里
- Linux内核源代码分析——fork()原理多进程网络模型
- linux磁盘管理------LVM
- javascript 高级程序设计_重读《JavaScript高级程序设计》
- Linux下java/bin目录下的命令集合
- AndroidStudio 编译异常java.lang.OutOfMemoryError: GC overhead limit exceeded
- row_number() over()排序功能
- web.config 测试账号
- Samba 共享目录设置在Home目录下
- 微信朋友圈api接口调用源码
- 赛门铁克为 Google 域名颁发证书
- visio2007或office 2007安装失败提示一个或多个受保护的windows文件导致office 2007安装失败
- modern cmake的概念剖析
- 【小技巧】Linux安装matlab教程
- 计算机芯片制造原理,从沙粒到芯片,原来CPU制造工序过程是这样的(视频)
- python核心底层_大话Python函数底层逻辑 - 北门吹雪 - 开发者的网上家园
热门文章
- 家用计算机历史记录,如何查看计算机使用历史记录,只需几个简单步骤即可查看...
- 云空调,GitHub 的专属冷气——GitHub 热点速览 v.21.20
- javascript实现电话号码验证
- 和ts一般怎么玩_TS夺冠后马上卖席位?微博电竞欲加盟,以后场场热搜安排上...
- 2012端午檀头山碧海蓝天海岛游~ ZZ
- 微软校招编程题Beautiful String的状态机解法
- 【机器学习应用】机器学习之无监督学习
- 皮查伊任谷歌母公司Alphabet CEO 创始人佩奇退位
- C语言用两个for循环轻松实现九九乘法表(99乘法表)
- 数字电路硬件设计系列(五)之AT89C51/C52最小系统设计