我们的登录系统,使用了php的session机制,与cookie相比,无疑它是很安全的。同时,为了提升用户体验,页面上大量的使用了ajax延迟加载,而这些加载的数据,多是要求登录的,也就是说加载时需要进行session的验证。

这样造成的结果是,用户打开一个页面,先看到页面框架load完毕,然后浏览器发出一堆的ajax请求,这些ajax请求变成了串行的!在网络或者服务器繁忙的时候,用户体验可想而知!

那为什么session会造成这样的后果呢?PHP手册上有这样的句子(http://www.php.net/manual/en/function.session-write-close.php

session data is locked to prevent concurrent writes only one script may operate on a session at any time

也就是说session_start函数调用后,会对session加锁,以避免其他web请求修改了session的内容,而且从这里可以看到,该锁是彻底的互斥锁。针对该问题,网上也有人给出了解决方案,即在session打开并使用完毕之后,立即session_write_close掉,以允许其他web请求正常进行。另外,既然函数名称为write close,经测试,调用之后,仍然可以读取$_SESSION中的值,但是写入则失败。

session_start();
$_SESSION[‘test’] = ‘abcd';
session_write_close();
$_SESSION[‘a’] = ‘aaaa';
var_dump($_SESSION);

这里,立即var_dump session可以看到a=>’aaaa’,但是它并没有真的写入,在其他页面进行请求,是请求不到的。

当然,另一方面,我们也可以使用cookie来避免这种竞争的存在。由于cookie对于用户是可见的,所以一些敏感内容不可以直接存储,需要进行加密。自己实现加密算法未免有些重复造轮子,所以我从Cake框架中摘取出了一段加密代码:

下载地址:http://flykobetest-xfiles.stor.sinaapp.com/2cfc19a8c680453cf374317c946bddad.txt

最近在做基于OAUTH的一些事情,其所需的oauth_token,oauth_token_secret,user_id原先都是以数组的形式存储在session中的。而cookie不支持array,而我又不想在一个域名下建立多个cookie的key,所以就可以将需要存储的数组转化为GET参数的形式,以&和=连接。这里需要注意的是,key和value中都可能出现我们的连接符号&和=,所以在编码前,请对key和value分别urlencode。

2 Comments

  1. 站长工具 says:

    博主,兔年快乐!

Leave a Reply