cookie和session工作原理

本文探讨了HTTP协议的无状态特性及其带来的挑战,并介绍了cookie和session两种状态保持机制的工作原理及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HTTP协议与状态保持 
HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。 

然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。 

让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案: 
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。 
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。 
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。 

由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。 

理解cookie机制 
cookie机制的基本原理就如上面的例子一样简单,但是还有几个问题需要解决:“会员卡”如何发;“会员卡”的内容;以及客户如何使用“会员卡”。 

正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。 

而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示,如果某家分店还发行了自己的会员卡,那么进这家店的时候除了要出示麦当劳的会员卡,还要出示这家店的会员卡。 
cookie的内容主要包括:名字,值,过期时间,路径和域。 
其中域可以指定某一个域比如.google.com,相当于总店招牌,比如宝洁公司,也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.com,可以用飘柔来做比。 
路径就是跟在域名后面的URL路径,比如/或者/foo等等,可以用某飘柔专柜做比。 
路径与域合在一起就构成了cookie的作用范围。 
如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。 

存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。 

下面就是一个goolge设置cookie的响应头的例子 
HTTP/1.1 302 Found 
Location: http://www.google.com/intl/zh-CN/ 
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com 
Content-Type: text/html 
浏览器在再次访问goolge的资源时自动向外发送cookie 

理解session机制 
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。 

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。 
由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid=ByOK ... 99zWpBng!-145788764 
另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764 
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。 
为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。 

另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。这种技术现在已较少应用,笔者接触过的很古老的iPlanet6(SunONE应用服务器的前身)就使用了这种技术。 
实际上这种技术可以简单的用对action应用URL重写来代替。 

在谈论session机制的时候,常常听到这样一种误解“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。 

恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。 


总结 
session机制本身并不复杂,然而其实现和配置上的灵活性却使得具体情况复杂多变。这也要求我们不能把仅仅某一次的经验或者某一个浏览器,服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析。
<think>嗯,用户问的是CookieSession工作原理,需要用中文来介绍。首先,我得回忆一下这两个概念的基本定义它们在Web开发中的作用。Cookie是存储在客户端的小型数据片段,而Session则是服务器端用来跟踪用户状态的一种机制。不过,我需要更详细地梳理它们的工作流程区别。 首先,用户可能已经知道HTTP协议是无状态的,所以需要CookieSession来维持状态。但用户可能不太清楚它们具体是怎么工作的,或者它们之间如何协同。我得解释清楚这两者之间的关系,以及为什么需要两者同时存在。 接下来,我应该分步骤说明Cookie工作原理。当用户第一次访问网站时,服务器会通过响应头Set-CookieCookie发送到浏览器,之后浏览器每次请求都会带上这个Cookie。需要提到Cookie的常见属性,比如名称、值、过期时间、域名、路径等。可能还要提到安全性相关的属性,比如HttpOnlySecure。 然后是Session的部分。Session数据存储在服务器端,每个用户有一个唯一的Session ID,这个ID通常通过Cookie传递给客户端。当客户端发送请求时,服务器通过这个Session ID来找到对应的Session数据。这里需要强调Session依赖于Cookie,但也可以有其他方式,比如URL重写,不过最常见的是Cookie。 还要比较两者的区别,比如存储位置、安全性、存储容量限制等。用户可能关心为什么有时候用Cookie,有时候用Session,或者它们的优缺点。比如,Cookie存储在客户端,可能被篡改,而Session在服务器更安全,但会增加服务器负担。 另外,可能需要举一个用户登录的例子来说明整个过程。比如用户登录后,服务器创建Session,将Session ID通过Cookie发送给浏览器,之后的请求携带这个Cookie,服务器验证后维持登录状态。 还要注意可能的误区,比如Session不一定必须依赖Cookie,但大多数情况下是这样的。或者Session的数据存储位置,比如内存、数据库、文件系统等,根据服务器配置不同而不同。 用户可能想知道安全性问题,比如如何防止Session劫持,这时候可能需要提到使用SecureHttpOnly属性,或者定期更换Session ID等措施。 最后,总结两者的协作关系,以及它们如何共同解决HTTP无状态的问题,保持用户会话状态。确保语言通俗易懂,避免太多技术术语,但也要准确。</think>好的!Cookie Session 是 Web 开发中用于解决 HTTP 协议**无状态性**的关键技术,它们共同协作来跟踪用户的会话状态。以下是它们的工作原理区别: --- ### **Cookie(客户端存储)** **定义**:Cookie 是由服务器生成的一小段文本数据,存储在用户的浏览器中。每次用户访问网站时,浏览器会自动将 Cookie 附加到请求头中发送给服务器。 #### **工作原理**: 1. **服务器创建**:当用户首次访问网站时,服务器通过 HTTP 响应头的 `Set-Cookie` 字段发送 Cookie 到浏览器。 ```http HTTP/1.1 200 OK Set-Cookie: user_id=123; Expires=Wed, 21 Oct 2025 07:28:00 GMT; Path=/; Secure; HttpOnly ``` 2. **浏览器存储**:浏览器将 Cookie 保存在本地(内存或硬盘,取决于过期时间)。 3. **自动发送**:后续用户每次请求该网站时,浏览器会自动将匹配的 Cookie 附加到请求头中: ```http GET /home HTTP/1.1 Cookie: user_id=123 ``` 4. **服务器读取**:服务器通过请求头的 Cookie 识别用户身份或状态。 #### **Cookie 的特性**: - **存储位置**:客户端(浏览器)。 - **容量限制**:通常每个域名下最多 4KB。 - **安全性**:可能被篡改(需结合加密或签名)。 - **常见用途**:保存登录凭证、用户偏好设置等。 --- ### **Session(服务器端存储)** **定义**:Session 是服务器用来存储用户会话信息的机制。服务器为每个用户分配一个唯一的 **Session ID**(通过 Cookie 或 URL 传递),并用此 ID 关联用户的数据。 #### **工作原理**: 1. **创建 Session**:用户首次访问时,服务器生成一个唯一的 Session ID,并创建对应的存储空间(如内存、数据库)。 2. **传递 Session ID**:服务器通过 `Set-Cookie` 将 Session ID 发送给浏览器(例如 `JSESSIONID=abc123`)。 3. **浏览器回传**:后续请求中,浏览器自动携带 Session ID(通过 Cookie 或 URL)。 4. **服务器验证**:服务器根据 Session ID 查找对应的 Session 数据,识别用户状态。 #### **Session 的特性**: - **存储位置**:服务器端(更安全)。 - **容量限制**:取决于服务器资源。 - **依赖 Cookie**:默认通过 Cookie 传递 Session ID(也可用 URL 重写,但不常见)。 - **常见用途**:保存登录状态、购物车内容等敏感信息。 --- ### **Cookie Session 的协作流程** 以用户登录为例: 1. 用户输入账号密码登录。 2. 服务器验证成功,创建 Session 数据(如用户角色、权限),生成 Session ID。 3. 服务器通过 `Set-Cookie` 将 Session ID 发送给浏览器。 4. 浏览器后续请求自动携带此 Cookie(含 Session ID)。 5. 服务器通过 Session ID 找到对应的 Session 数据,确认用户已登录。 --- ### **关键区别** | **特性** | Cookie | Session | |----------------|---------------------------------|-----------------------------| | **存储位置** | 客户端(浏览器) | 服务器端 | | **安全性** | 较低(可能被篡改) | 较高(数据在服务器) | | **存储容量** | 小(约 4KB/域名) | 大(受服务器资源限制) | | **性能影响** | 无(数据在客户端) | 可能影响服务器性能 | | **生命周期** | 可设置长期有效(如过期时间) | 通常随会话结束(如关闭浏览器)失效 | --- ### **安全问题** - **Cookie 泄露**:若被窃取(如 XSS 攻击),可能导致 Session 劫持。解决方案:使用 `HttpOnly`(防止 JS 读取)、`Secure`(仅 HTTPS 传输)。 - **Session 固定攻击**:攻击者强制用户使用已知的 Session ID。解决方案:登录后重置 Session ID。 --- ### **总结** - **Cookie** 是客户端存储的“钥匙”,**Session** 是服务器存储的“保险箱”。 - Cookie 适合存储非敏感信息(如用户偏好),Session 适合存储敏感数据(如登录状态)。 - 两者配合解决了 HTTP 无状态的问题,实现了用户会话的持续跟踪。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值