Session 和 Cookie 有什么关系
上面提到,session_id 可以通过 URL 或 cookie 来传递,由于 URL 的方式比 cookie 的方式更加不安全且使用不方便,所以一般是采用 cookie 来传递 session_id.
为什么不推荐使用 PHP 自带的 files 型 Session 处理器
在 PHP 中,默认的 Session 处理器是 files,处理器可以用户自己实现(参见:自定义会话管理器).我知道的成熟的 Session 处理器还有很多:Redis、Memcached、MongoDB......
为什么不推荐使用 PHP 自带的 files 类型处理器,PHP 官方手册中给出过这样一段 Note:
无论是通过调用函数 session_start() 手动开启会话, 还是使用配置项 session.auto_start 自动开启会话, 对于基于文件的会话数据保存(PHP 的默认行为)而言, 在会话开始的时候都会给会话数据文件加锁, 直到 PHP 脚本执行完毕或者显式调用 session_write_close() 来保存会话数据. 在此期间,其他脚本不可以访问同一个会话数据文件.
上述引用参见:Session 的基本用法
php
session_start();
var_dump($_SESSION);
例如:
$_SESSION['name'] = 'Jing';
session_write_close();
$_SESSION['name'] = 'Mr.Jing';
官方给出的方案:
对于大量使用 Ajax 或者并发请求的网站而言,这可能是一个严重的问题. 解决这个问题最简单的做法是如果修改了会话中的变量, 那么应该尽快调用 session_write_close() 来保存会话数据并释放文件锁. 还有一种选择就是使用支持并发操作的会话保存管理器来替代文件会话保存管理器.
我推荐的方式是使用 Redis 作为 Session 的处理器.
拓展阅读:
为什么不能用 memcached 存储 Session
如何使用 Redis 作为 PHP Session handler
Session 数据是什么时候被删除的
这是一道经常被面试官问起的问题.
先看看官方手册中的说明:
继续用我上面那个不太恰当的比方吧:如果我们把物品放在超市的储物箱中而不取走,过了很久(比如一个月),那么保安就要清理这些储物箱中的物品了.当然并不是超过期限了保安就一定会来清理,也许他懒,又或者他压根就没有想起来这件事情.
再看看两段手册的引用:
GC 的运行时机并不是精准的,带有一定的或然性,所以这个设置项并不能确保旧的会话数据被删除.某些会话存储处理模块不使用此设置项.
对于这种删除机制,我是存疑的.
还有,GC 进程启动后都需要遍历 Session 文件列表,对比文件的修改时间和服务端的当前时间,判断文件是否过期而决定是否删除文件.
这也是我觉得不应该使用 PHP 自带的 files 型 Session 处理器的原因.而 Redis 或 Memcached 天生就支持 key/value 过期机制的,用于作为会话处理器很合适.或者自己实现一个基于文件的处理器,当根据 session_id 获取对应的单个 Session 文件时判断文件是否过期.
为什么重启浏览器后 Session 数据就取不到了
session.cookie_lifetime 以秒数指定了发送到浏览器的 cookie 的生命周期.值为 0 表示"直到关闭浏览器".默认为 0.
其实,并不是 Session 数据被删除(也有可能是,概率比较小,参见上一节).只是关闭浏览器时,保存 session_id 的 Cookie 没有了.也就是你弄丢了打开超市储物箱的钥匙(session_id).
同理,浏览器 Cookie 被手动清除或者其他软件清除也会造成这个结果.
为什么浏览器开着,我很久没有操作就被登出了
这个是称为"防呆",为了保护用户账户安全的.
这个小节放进来,是因为这个功能的实现可能和 Session 的删除机制有关(之所以说是可能,是因为这个功能不一定要借住 Session 实现,用 Cookie 也同样可以实现). 说简单一点,就是长时间没有操作,服务端的 Session 文件过期被删除了.
一个有意思的事情
在我试验的过程中,发现了小有意思的事情:我把 GC 启动的概率设置为 100%.如果只有一个访问者请求,该访问者即使过了很久(超过了过期时间)后才发起第二次请求,那么 Session 数据也还是存在的('session.save_path' 目录下面的 Session 文件存在).是的,明明就超过了过期时间,却没有被 GC 删除.这时,我用另外一个浏览器访问时(相对于另一个访问者),这次请求生成了新的 Session 文件,而上一个浏览器请求生成的那个 Session 文件终于没有了(之前那个 Session 文件在 'session.save_path' 目录下面的消失了).
还有,发现 Session 文件被删除后,再次请求,还是会生成和之前文件名相同的 Session 文件(因为浏览器并没有关闭,再次请求发送的 session_id 是相同的,所以重新生成的 Session 文件的文件名还是一样的).但是,我不理解的是:这个重新出现的文件的创建时间竟然是第一次的那个创建时间,难道它是从回收站中回来的?(确实,我做这个试验时是在 window 下进行的)
我猜测的原因是这样:当启动会话后,PHP 根据 session_id 找到并打开了对应的 Session 文件,然后才启动 GC 进程.GC 进程就只检查除了当前这个 Session 文件外的其他文件,发现过期的就干掉.所有,即使当前这个 Session 文件已经过期了,GC 也没有删除它.
我认为这个不合理的.
由于发生这种情况影响也不大(毕竟线上请求很多,当前请求的过期文件被其他请求唤起的 GC 干掉的可能性是比较大的) + 我没有信心去看 PHP 源代码 + 我并不在线上使用 PHP 自带的 files 型 Session 处理器.所以,这个问题我就没有深入研究了.请谅解.
// GC 启动概率设置为 100%
ini_set('session.gc_probability', '100');
①.、命令注入(Command Injection)
②.、eval注入(Eval Injection)
④.、跨网站脚本攻击(Cross Site Scripting, XSS)
⑤.、SQL注入攻击(SQL injection)
⑥.、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)
⑦.、Session 会话劫持(Session Hijacking)
⑧.、Session 固定攻击(Session Fixation)
⑨.、HTTP响应拆分攻击(HTTP Response Splitting)
①.0、文件上传漏洞(File Upload Attack)
①.1、目录穿越漏洞(Directory Traversal)
以上就是土嘎嘎小编为大家整理的phpsession劫持相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!