PHP网络技术(六)——session及与cookie的比较

PHP网络技术(六)

——session及与cookie的比较

(原创内容,转载请注明来源,谢谢)

一、概念

session是持续的、双向性的连接。其是通过在cookie中存储sessionID,实现session的传递,以区分不同用户的session。

与cookie的存储方式不同,session存储在服务端,每个session一个文件进行存储。通过上述的sessionID,可以获取不同的session文件。session文件名是sess_32位随机字符串,里面的内容形如:变量名|类型:长度:值。

PHP在使用session之前,需要有session_start()命令。

二、原理

由于HTTP不支持服务端保存客户端的信息,因此引入session的概念。

session通过一个称为PHPSESSID的cookie和服务器联系,其通过sessionID判断客户端的用户,即session的文件名。因此,通常情况下,使用session前提是浏览器支持且启用cookie(浏览器不支持的情况下也可以使用,具体实现方式下面会提到)。

session实际上是在客户端和服务器之间通过HTTP Request和HTTP Response进行互传,其中sessionID按照特定的算法生成,包含在HTTP Request里面,具有唯一性和随机性。

和cookie一样,如果没有设置失效时间,浏览器关闭后session文件自动注销,当重新请求时会重新注册一个sessionID。当客户端没有禁用cookie,cookie会在启用session会话时存储sessionID及其生命周期,也可以通过cookie设置session的生命周期。方法如下:

         setcookie(session_name(),session_id(), time()+3600, ‘/’, ‘127.0.0.1’, false, true)

设置了session过期方式,则在过期后由浏览器进行回收,如果未过期,则浏览器关闭后再打开仍有效。

三、浏览器禁用cookie时的处理方式

默认情况下,由cookie存储sessionID,并且自动发送给服务端,服务端由此进行判断sessionID并且取出相应的session文件。但是,如果浏览器禁止了session,则无法通过cookie获取sessionID,则需要另辟蹊径。

常用的做法是通过URL将sessionID从客户端传递给服务端,服务端采用get的方式获取并从服务端本地获取相应sessionID对应的session文件。如果没有则获取失败。

代码如下;

客户端:client.php

         $sessionName= session_name();
         $sessionID= session_id();
         echo‘<a href=”server.php?’.$sessionName.’=’.$sessionID.’”>跳转</a>’;

服务端: server.php

         $sessionName= session_name();
         $sessionID= $_GET[$sessionName];
         session_id($sessionID);
         session_start();

四、session存储

当有大量的session进行操作时,则对session进行存储并取出的效率更高。通常的做法是实现PHP的接口session_set_save_handler(callback open, callback close, callbackread, callback write, callback destroy, callback gc)。

另外,由于在关系型数据库中存储效率较低,建议采用非关系型数据库或缓存进行存储,如memcache或redis,效率会更高。

五、关于cookie与session

1)存储位置

cookie数据存放在客户的浏览器上,session数据放在服务器上,但是sessionID作为一个cookie存储在客户端(除非客户端禁用cookie,则需要使用上述url传参的方式实现)。

2)安全性

session相对cookie来说安全,但是cookie和session的安全性差距不大,因为cookie和session是通过sessionID绑定的,因此获取到cookie后,发送给服务器,服务器通过cookie就会进行验证。因此,安全性主要还是需要在代码中进行实现。

另外,为了防止cookie劫持(将其他人的电脑里的cookie复制到自己的电脑,使自己有其他人电脑的cookie,进而进行相应的操作),下需要在cookie中加入IP、UA等特殊信息,并在服务器进行比对。

3)跨软件

由于cookie是不同的客户端各自存储,因此不同的浏览器无法共用cookie。而session由于是存储在服务器,因此不受软件影响。但是由于sessionID是存储在cookie中的,因此通常情况下跨浏览器也无法正确读取到session。

4)资源占用

cookie在每次HTTP请求中都会发出,无论是客户端还是服务端,因此cookie主要是占用带宽。session是存储在服务端,并不进行传输,因此不占带宽,但是由于存储在服务端,因此占用服务端的存储并且读写session占用服务端的IO。

因此,高并发情况下,服务端需要同时读取多个session文件,对服务端造成压力较大,cookie存在的问题则是占用带宽较多。

因此减轻服务器性能方面需要使用cookie,减少网络压力使用session。

5)限制条件

每个cookie保存的数据不能超过4kb,且一般浏览器对每个域名下的cookie还有数量的限制,另外浏览器也可以设置禁止cookie。就此方面来说,session不受限制。

6)使用场景

通常情况下,cookie用于安全性不那么高的地方,如记住用户名。并且可以在使用cookie时通过判断IP、UA或其他加密信息进行校验,防止cookie劫持。要存储用户名也可以将用户名通过md1等不可逆算法加盐或者其他方式进行加密,并且后台再次进行判断,达到保存密码的功能。

验证登陆的功能通常用session实现。即在登陆页面验证成功后,将内容写入session。并且,为了在后面的每个页面都进行判断,当判断成功时,会再次重设session的时间;当验证失败或者超时导致session注销,则跳转到登陆页。这就是实现超时没有操作需要重新登陆的原理。在mvc或其他单一入口的方式下,通常会将验证session和重设时间的方法写在basecontroller(基类),其他文件继承该类进行验证session信息与重置session过期时间。

——written by linhxx 2017.07.24

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2132
来自专栏Golang语言社区

【Golang语言社区】GO1.9 map并发安全测试

var m sync.Map //全局 func maintest() { // 第一个 YongHuomap := make(map[st...

4688
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

5346
来自专栏杨龙飞前端

scrollto 到指定位置

2494
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2677
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

3975
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2527
来自专栏魂祭心

原 canvas绘制clock

4034
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2622

扫码关注云+社区