最近 个项目 里面有 个比较大 表单 用户完成它需要很多时间 很多用户花了千辛万苦完成的后 提交发现SESSION过期 系统退出了 所以引起了研究如何设置SESSION以及保持SESSION在线 需要 下面是 些心得体会体会
什么是SESSION?
按照WIKI 解释 SESSION是存在于两个通信设备间 交互信息 在某 时间建立 经过 定 时间后失效 常见 SESSION有:TCP SESSION、WEB SESSION(HTTP SESSION)、LOGIN SESSION等
根据OSI模型中 会话实现 位置区别 SESSION主要分为几种 种是应用层会话 包括WEB SESSION(HTTP SESSION)和telnet远程登录session;会话层实现 包括Session Initiation Protocol(SIP)和Internet Phone Call;在传输层实现 有TCP SESSION
本文主要讨论WEB SESSION 其 般有两种:客户端SESSION和服务器端SESSION 后 种最常见 属于Java Beans提供
SESSION是做什么 ?
在计算机领域 特别是网络方面 SESSION使用 特别广泛 也可以称为是对话(Dialogue)、会话等 般是指在两个通信设备间存储 状态 有时也发生在用户和计算机的间(Login SESSION)
区别于无状态 通信 SESSION通常用来存储通信状态 因此通信 双方至少有 方需要存储SESSION 历史记录 从而实现两者间 通信
SESSION(WEB SESSION)是如何实现 ?
浏览器和服务器的间进行HTTP通信时 通常会包含 个 HTTP Cookie 来标识状态 通常会有 个唯 SESSIONID SESSION通常记录着用户 些验证信息和级别
在几中编程语言中最常用 Http Session Token是 JSESSIONID(JSP) PHPSESSID(PHP) ASPSESSIONID(ASP) 这个标识通常由哈希 产生 能够唯 表示这个用户 身份 在服务器和客户端通信时 作为GET或者POST 参数存储在客户端
SESSION 实现方式通常有两种 服务器端SESSION和客户端SESSION 两种方式各有优缺点
服务器端SESSION实现容易并且效率比较高 但是遇到负载均衡或者高可用性需求 时候 处理起来就比较困难 对于那种内生系统不存在存储设备 时候 也是不可用 负载均衡可以通过共享文件系统或者强制客户只能登录到 台服务器上来实现 但是这样会降低效率 对于没有存储 设备 也可以通过使用RAM(参考参考资料6)来解决服务器端SESSION 实现 这种思路方法这对哪些客户端链接有限 系统有效(诸如路由或者接入点设备)
客户端SESSION 使用可以解决服务器端SESSION 些问题 比如避免了负载均衡 算法等 但是同时也会产生 些自身 问题 客户端SESSION使用Cookie和加密技术来在区别 请求间保存状态 在每 个动态页面结束后 会统计当前 SESSION 并把它发回客户端 每次成功请求后 会把cookie再发送到服务器端 来让服务器“记起”这个用户 身份 客户端SESSION最重要 问题就是安全问题 旦cookie被劫持或者篡改了 用户 信息 安全性就丧失了
PHP中如何设置SESSION?
搭建好PHP 开发环境后 通过phpinfo 可以查看到和SESSION有关 部分包括:
SESSION模块 在PHP V5.2.9版本中 共有25个变量 其中 平时设置中常会用到 几个有:
session.cookie_l etime 设置存储SESSIONID cookie过期时间
session.name SESSION COOKIE名称 默认为PHPSESSID
session.save_handler SESSION 存储方式 默认为FILE
session.save_path Fedora下面默认存储在/var/lib/php/session
session.gc_probability
session.gc_divisor
session.gc_maxl etime 这 3个选项用来处理GC机制发生 机率
session.cache_limiter (nocache,private,private_no_expire,public)
session.cache_expire 这两个选项是用来缓存CacheSESSION 页面
先来考虑第 个问题 SESSION多久会过期 他是如何过期 ?如果要在PHP 中使用SESSION 定要先引用session_start 这个 执行 就会在SESSION 存储目录(如果使用了file handler)生成 个SESSION文件 里面内容是空 同时浏览器会见里 个name为PHPSESSID cookie 里面存储着 个hash出来 SESSION 名字
SESSION 过期依赖于 个垃圾回收机制(Garbage Collection) SESSION创建后作为 个文件存放在服务器上 客户端脚本每访问 次SESSION中 变量 SESSION文件 访问时间就会进行更新 每次访问都是根据客户端存储 SESSIONID去请求服务器中存储 唯 SESSION 当客户端 cookie过期后 就无法知道要访问 是哪 个SESSION 尽管此时服务器上 SESSION文件还没有被过期收回 这样就会造成服务器资源 浪费
但是同时 如果我们希望用户 session马上过期 话 我们就可以通过设置cookie 办法来实现 SESSION 回收是在每次访问页面 时候进行 回收 机率由session.gc_probability session_gc_divisor指定 默认士1/100 如果设置为1 则每次超过了SESSION 生存周期去访问 话 SESSION 定会被回收
两种需求:1、保持SESSION不过期或延长SESSION过期时间;2、使SESSION立即过期
1、保持SESSION不过期和延长SESSION过期时间非常必要 特别是在内部应用系统中或者有很大 表单 时候 想想你 老板在填写 个表单 刚好碰上午饭时间 留着这个表单等吃饭回来 填写完剩余 内容 提交后他看到什么 般来说都是 个登录界面 想要提高用户体验 关键是要让老板 表单不出问题 我们就必须延长SESSION 生存周期
保持SESSION不过期和延长SESSION过期时间 可以通过设置session.gc_maxl etime来实现 不过首先需要保证客户端 cookie不会在gc执行回收的前失效 通过设置 个较长 gc_maxl etime可以实现延长session 生存周期 可是对于不是所有请求都会保持很久 应用来说 这么做对于服务器配置显然不是 个最佳 选择
我们知道SESSION 回收机制是根据SESSION文件 最后访问时间来判断 如果超过了maxl etime 则根据回收机率进行回收 所以我们只需要定期 去访问 下SESSION就可以了 而这可以通过刷新页面来实现 根据这个思路 解决 思路方法就有了
通过JS定期 去访问页面;
利用Iframe定期 刷新页面;
直接利用 发送HTTP请求 这样就可以避免在页面中嵌入其他 元素;
下面是利用JS发送请求实现 保持SESSION不过期 实现思路方法 这样我们就只需要在需要SESSION保持长时间 页面(比如大表单页面)
<script type="text/javascript">
function keepMeAlive(imgName){
myImg = document.getElementById(imgName);
(myImg) myImg.src = myImg.src.replace(//?.*$/, '?' + Math.random );
}
window. Interval("keepMeAlive('phpImg');", 4000);
</script>
<img id="phpImg" src="http://www.phpplot.com/phpplot/session/sess_refresh.php?" width="1" height="1" />
其中URL后加入 个随机数是为了避免这个链接 请求被浏览器缓存Cache
2、使SESSION立即过期 思路方法就比较多了 我们可以session_destroy 也可以用上面 思路 请求 个session_destroy 页面
SESSION安全吗?
PHP 手册中明确写出:SESSION并不能保证储存在SESSION中 信息 定只能被他 创建者所看到
如果想要安全 处理 些远程 操作 那么HTTPS是唯 选择 最基本 不要认为 个用户信息在SESSION中存在就认为这个用户 定就是他本人 虽然SESSION中 信息会给你他已经经过了用户名和密码验证 假象 所以 如果需要做 些修改密码或者类似 事情 时候 让用户重新输入密码是 个比较好 选择
早期 Apache版本并没有采用COOKIE 方式来存储PHPSESSID 而是采用 URL-rewrite 也就是每个URL后面都会加上PHPSESSID=<sessionid>来表明它属于那个激活 SESSION 新版 Apache已经将这个属性设置为默认关闭
session.use_trans_id = 0;
所以从这个意义上来讲 延长SESSION 时间过长或者保持SESSION 直在线对于安全来说始终不是 件好事情 终极 解决办法就是用户提交跳转到登录窗口 登录后又能够回到填写页面 并且所有 数据都还在 这个 实现方式现在用Ajax来解决应该没什么困难 每隔 定时间就把当前 用户数据POST到 个存储位置 不管是XML或者JSON
拾遗:
对于客户端不支持JavaScript 情况可以采用 思路方法:
1、写 个浮层 显示在最顶层 如果用户未禁用JS 则让浮层消失;
2、将所有 INPUT都设置为disable 然后再用JS设置为enabled;
以上这两种方式都是在JS被禁用 时候 所有功能都不能用 如何在JS被禁用 情况下使我们 应用仍然正常工作 这个貌似就比较困难 实现这个 所花 时间和所收到 效果大家要权衡 下
http://www.crazycoder.cn/Php/Article65686.html