热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP中怎样保持SESSION不过期原理及方案介绍

本文主要讨论WEBSESSION,其一般有两种:客户端SESSION和服务器端SESSION,后一种最常见的属于JavaBeans提供的
PHP中如何保持SESSION以及由此引发的一些思考 最近的一个项目,里面有一个比较大的表单,用户完成它需要很多时间,很多用户花了千辛万苦完成之后,一提交发现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_lifetime 设置存储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_pisor
session.gc_maxlifetime 这三个选项用来处理GC机制发生的机率
session.cache_limiter (nocache,private,private_no_expire,public)
session.cache_expire 这两个选项是用来缓存SESSION的页面


先来考虑第一个问题,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_pisor指定,默认士1/100。如果设置为1,则每次 超过了SESSION的生存周期去访问的话,SESSION一定会被回收。

两种需求:
1、保持SESSION不过期或延长SESSION过期时间;
2、使SESSION立即过期。

1、保持SESSION不过期和延长SESSION过期时间非常必要,特别是在内部应用系统中或者有很大的表单的时候。想想你的老板在填写一个表单,刚好 碰上午饭时间,留着这个表单等吃饭回来,填写完剩余的内容,提交后他看到什么,一般来说都是一个登录界面。想要提高用户体验,关键是要让老板的表单不出问 题,我们就必须延长SESSION的生存周期。

保持SESSION不过期和延长SESSION过期时间,可以通过设置session.gc_maxlifetime来实现,不过首先需要保证客户端的 COOKIE不会在gc执行回收之前失效。通过设置一个较长的gc_maxlifetime可以实现延长session的生存周期,可是对于不是所有请求 都会保持很久的应用来说,这么做对于服务器配置显然不是一个最佳的选择。
我们知道SESSION的回收机制是根据SESSION文件的最后访问时间来判断的,如果超过了maxlifetime,则根据回收机率进行回收。所以我们只需要定期的去访问一下SESSION就可以了,而这可以通过刷新页面来实现,根据这个思路,解决的方法就有了。

通过JS定期的去访问页面;
利用Iframe定期的刷新页面;

直接利用程序发送HTTP请求,这样就可以避免在页面中嵌入其他的元素;

下面是利用JS发送请求实现的保持SESSION不过期的实现方法,这样我们就只需要在需要SESSION保持长时间的页面(比如大表单页面)。

代码如下:





其中URL后加入一个随机数是为了避免这个链接的请求被浏览器缓存。

2、使SESSION立即过期的方法就比较多了,我们可以session_destroy(),也可以用上面的思路,请求一个session_destroy的页面。

SESSION安全吗?
PHP的手册中明确写出:SESSION并不能保证储存在SESSION中的信息一定只能被他的创建者所看到。

如果想要安全的处理一些远程的操作,那么HTTPS是唯一的选择。最基本的,不要认为一个用户信息在SESSION中存在就认为这个用户一定就是他本人, 虽然SESSION中的信息会给你他已经经过了用户名和密码验证的假象。所以,如果需要做一些修改密码或者类似的事情的时候,让用户重新输入密码是一个比 较好的选择。

早期的Apache版本并没有采用COOKIE的方式来存储PHPSESSID,而是采用的URL-rewrite,也就是每个URL后面都会加上 PHPSESSID=来表明它属于那个激活的SESSION,新版的Apache已经将这个属性设置为默认关闭。

代码如下:


session.use_trans_id = 0;


所以从这个意义上来讲,延长SESSION的时间过长或者保持SESSION一直在线对于安全来说始终不是一件好事情。终极的解决办法就是用户提交跳转到 登录窗口,登录后又能够回到填写页面,并且所有的数据都还在。这个的实现方式现在用Ajax来解决应该没什么困难,每隔一定时间就把当前的用户数据 POST到一个存储位置,不管是XML或者JSON。

拾遗:
对于客户端不支持Javascript的情况可以采用的方法:
1、写一个浮层,显示在最顶层,如果用户未禁用JS,则让浮层消失;
2、将所有的INPUT都设置为disable,然后再用JS设置为enabled;
以上这两种方式都是在JS被禁用的时候,所有功能都不能用,如何在JS被禁用的情况下使我们的应用仍然正常工作,这个貌似就比较困难。实现这个的所花的时间和所收到的效果大家要权衡一下。

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
author-avatar
书友62908490
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有