首页 » Web前端 » phpsession并发技巧_php的session和并发

phpsession并发技巧_php的session和并发

访客 2024-12-03 0

扫一扫用手机浏览

文章目录 [+]

我登录不明晰

某天,我准备登录我们一个后台系统,前去办理一个bug,在账户密码验证码都准确输入的情形下,我登录不上,经由多次实验创造紧张有两个缺点信息:

phpsession并发技巧_php的session和并发

csrf验证失落败验证码缺点【我对码神赌咒我用半角输入了我看到的验证码,且顺序同等,无多加字符】

phpsession并发技巧_php的session和并发
(图片来自网络侵删)
我们的系统

我们的系统是基于phalcon 2.0.8 开拓的,如你所见,我们在表单域加入了防止csrf攻击的域。
也启用了验证码。

我首先对这两个组件进行查阅,创造他们都是将数据存于session:

# phalcon/security.zep# Security::getTokenlet session =

$this->session->set('admin_get_captcha_action', $captcha);

然后我又查阅了我们session的实现,创造是将数据存储于redis的。

找啊找

什么问题导致我登录不上呢?既然是数据验证上涌现问题,就从数据动手吧,我上岸我们测试环境的redis机器,实行 redis-cli monitor,然后走一遍登录流程,创造输出如下(意思意思):

GET sessionId GET sessionId SETEX sessionId 3600 csrf=xxxx SETEX sessionId 3600 captcha=abcd

我们可以看到:

这里存在两次要求,一次是表单加载,一次是天生验证码的。
存在“并发”的情形,这两个要求该当是表单加载渲染后才要求验证码的,也便是session顺序该当是get->set->get->set,看起来怎么是并发要求了。
后面那个SETEX没有csrf的内容,也便是覆盖掉前面的数据了

全体天下都不好了,不过也轻微明白是什么问题了。
什么问题呢,说来话长,要从PHP的session数据的存取提及。

php的session数据的存取

session的数据是经由编码成字符串存储在存储器【file、db、redis、memcache等】的,在我们利用session的时候,是什么时候去储存器取数据的?又是什么时候将数据写入存储器的?

这个问题的答案可能和一些朋友想的不一样,一个要求里面,PHP只会读取一次存储器,在session_start的时候,然后也只会写入一次存储器,在要求结束的时候,或调用session_write_close的时候,将数据刷回存储器,关闭session。

那么问题来了:

如果一个会话,同时涌现两个读写session要求,没有担保获取1-写入1-获取2-写入2,同时没有cas版本管理机制的情形下,这些并发要求就会彼此读取不到对方的写入,末了写入的会把前面要求写入的session覆盖掉。
如果要求是串行的,像登录页面的表单和验证码,也有可能前面的要求已经输出内容了,但是session还没写入,后面的要求就已经发起了。

锁与不锁

办理这种资源的并发一样平常会通过锁或版本管理来处理。
但是版本管理我看不到好的方法。
就聊聊锁吧。

实在锁是不大适宜,有弊端的。

php的session,默认是用文件存储的,在打开session的时候,会对文件加独占锁,这样,其它要求就无法获取锁了,只能等待直到前面的锁解了。

这样担保了 读取-写入,读取-写入的顺序。

其它存储器,例如mysql,可以借助select for update进行行锁。
redis可以通过一个自增键,返回1的获取到锁等来实现。

这个实现的话,对数据流来说很空想,但是,对付目前这种页面大量运用ajax的情形,所有要求排队处理,将大大加大页面展现的耗时,乃至涌现要求超时等不可用故障。

没有办理的办理不建议过多利用session,其一次读取一次写入的机制所引发的问题,会造成坑的存在。
在模版渲染前,或要求输出前调用session_write_close

# 急速回写session,避免session覆盖$eventManager = $this->view->getEventsManager;if (!$eventManager) { $eventManager = new Manager; $this->view->setEventsManager($eventManager);}$eventManager->attach(\公众view:afterRender\"大众,function{ session_write_close;});return $this->view;

if($login) { # 急速回写session,避免session读取不到 $eventManager = $this->dispatcher->getEventsManager; if (!$eventManager) { $eventManager = new Manager; $this->dispatcher->setEventsManager($eventManager); } $eventManager->attach('dispatch:afterDispatchLoop',function{ session_write_close; }); return $this->response->setHeader('Location', '/');}

标签:

相关文章

语言本体调查,探寻语言发展的奥秘

语言是人类社会不可或缺的交流工具,它承载着丰富的文化内涵和智慧结晶。为了更好地了解和把握语言发展的规律,语言学家们开展了大量的语言...

Web前端 2024-12-29 阅读0 评论0

语言栏启动项,智能时代的沟通利器

随着科技的飞速发展,人工智能已经逐渐渗透到我们的日常生活中。而在这其中,语言栏启动项作为一种新兴的技术,正逐渐成为人们沟通的得力助...

Web前端 2024-12-29 阅读0 评论0

语言治疗,呵护言语,重拾沟通之美

语言治疗,简称“语疗”,是一门专注于改善患者言语、语言和沟通障碍的医学领域。在我国,随着社会的发展和生活节奏的加快,越来越多的人受...

Web前端 2024-12-29 阅读0 评论0

语言播报技术,未来沟通的桥梁

随着科技的飞速发展,人工智能逐渐成为我们生活中不可或缺的一部分。在众多人工智能应用中,语言播报技术以其独特的魅力,正逐渐改变着我们...

Web前端 2024-12-29 阅读0 评论0