最近
个项目
里面有
个比较大
表单
用户完成它需要很多时间
很多用户花了千辛万苦完成的后
提交发现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