Session与Cookie的理解

来源:互联网 发布:购买的域名如何解析 编辑:程序博客网 时间:2024/05/16 04:22

Session与Cookie的理解:

前言:

  • 今天Big-man公司的Boss询问了Big-man一个问题,问题是”如何理解Session?”,当时的Big-man理解为JS中的sessionStorage,按照sessionStorage去理解session,当然是要吃闭门羹了。被打击一塌糊涂。所以Big-man今日需要去好好理解一下这个session

  • 在理解session之前,Big-man需要去理解一下什么是Cookie

Cookie定义:

  • cookie是当前识别用户实现持久会话的最好方式。cookie最初由Netscape(网景)公司创建, 但现在所有主要的浏览求都支持它。
  • cookie的存在也影响了缓存, 大多数缓存浏览器不允许对任何cookie的内容进行缓存

cookie的类型:

  • 会话cookie:
    • 一种临时cookie, 它记录了用户访问站点时设置偏好。用户退出浏览器时,会话cookie就被删除了。
  • 持久cookie:
    • 生存时间比起会话cookie要更长一些,持久cookie存储在硬盘上,浏览器退出,计算机重启时它们仍然存在。通常会用持久cookie维护某个用户会周期性访问的站点的配置文件登录名
  • 会话cookie和持久cookie之间唯一的区别就是它们的过期时间。
  • 如果设置了Discard参数,或者没有设置ExpiresMax-Age参数来说明扩展的过期时间,这个cookie就是一个会话。

cookie是如何工作的:

  • cookie就像服务器给用户贴的”嗨,我叫”的贴纸一样。用户访问一个Web站点时,这个Web站点就可以读取那个服务器贴在用户身上的所有贴纸。
  • 用户首次访问Web站点时,Web服务器对用户一无所知。Web服务器希望这个用户会再次回来,所以想给这个用户”拍上”一个都有的cookie, 这样以后它就可以识别出这个用户了。cookie中包含了一个由名字=值(name=value),这样的信息构成的任意列表,并通过Set-CookieSet-Cookie2HTTP响应(扩展)首部将其贴到用户身上去。
    cookie工作工程
  • cookie中可以包含任意信息,但它们通常都只包含一个服务器为了进行跟踪而产生独特识别码
  • 比如上图中的(b)中, 服务器会将一个表示id="34294"cookie贴到用户上去。服务器可以用这个数字来查找服务器为其访问者积累的数据库信息(购物历史,地址信息等)。
  • 但是, cookie并不仅限于ID号。很多Web服务都会将信息直接保存在cookie中。
  • 比如:
    Cookie: name="Brian Totty"; phone="555-1212" 
  • 浏览器会记住从服务器返回的Set-CookieSet-Cookie2首部中的cookie内容, 并将cookie集存储在浏览器的cookie数据库中(把它当作一个贴有不同国家贴纸的旅行箱)。
  • 将来用户返回同一个站点时上图中的(c),浏览器会挑中那个服务器贴到用户上的那些cookie, 并在一个cookie请求首部中将其传回去。

cookie罐: 客户端的状态

  • cookie的基本思想就是让浏览器积累一组服务器特有的信息,每次访问服务器时都将这些信息提供给它。因为浏览器要负责存储cookie信息,所以此系统被称为客户端侧状态(Client-side state)。这个cookie规范的正式名称为HTTP状态管理机制(HTTP state management mechanism)。

网景的Navigatorcookie:

  • 不同的浏览会以不同的方式来存储cookie。网景的Navigator会将cookie存储在一个名为cookie.txt的文本文件中。例如:
# Netscape HTTP Cookie File# http://www.netscape.com/newsref/std/cookie_spec.html# This is a generated file! Do not edit.#
  • 下表是它的一个分析:
domain allh path secure expires name value www.fedex.com FALSE / FALSE 1136109676 cc /us/ .bankofamericaonline.com TRUE / FALSE 1009789256 state CA

- 文本文件中的每一行都代表一个cookie。有7个用tab键分隔的字段。
- domain(域 )——cookie的域。
- allh —— 是域中所有主机获取cookie,还是只有指定了名字的主机获取。
- path(路径)——域中与cookie相关的路径前缀。
- secure(安全)——是否只有在使用SSL连接时才发送这个cookie。
- expiration(过期)——从格林尼治标准时间1970年1月1日00:00:00开始的cookie过期秒数。
- name(名字)——cookie变量的名字。
- value(值)——cookie变量的值。

微软Internet Explorer的cookie:

  • 微软的Internet Explorer将cookie存储在高速缓存目录下独立的文本文件中。可以通过浏览这个目录来查看cookie。至于目录在什么地方可以仔细地去查找一下自己的系统。

不同站点使用不同的cookie:

  • Big-man在这里试想了一下,如果所有站点使用的是相同的cookie,会是什么样的场景,Big-man不敢继续往下想了,浏览器内部的cookie罐中可以有成百上千个cookie, 但浏览器不会将每个cookie都发送给所有的站点。在实际的应用中, 通常只向每个站点发送2~3个cookie。原因如下:
    • 对所有这些cookie字节进行传输会严重降低性能。浏览器实际传输的cookie字节数比实际的内容字节数多。
    • cookie中包含的是服务器特有的名值对,所以对大部分站点来说,大多数cookie都只是无法识别的无用数据
    • 将所有的cookie发送给所有站点会引发潜在的隐私问题,那些你并不信任的站点也会获得你只想发给其他站点的信息。
  • 很多Web站点都会与第三方厂商达成协议,由其来管理广告。这些广告被做得像Web站点的一个组成部分,而且它们确实发送了持久cookie。用户访问另一个由同一广告公司提供的服务站点时,(由于域是匹配的)浏览器就会再次回送早先设置的持久cookie。营销公司可以将此技术与Referer首部结合,暗地里构建一个用户档案和浏览习惯的详尽数据集。现代的浏览器都允许用户对隐私特性进行设置,以限制第三方cookie的使用。

cookie的域属性:

  • 产生cookie的服务器可以向Set-Cookie响应首部添加一个Domain属性来控制哪些站点可以看到那个cookie。比如,下面的HTTP响应首部就是在告诉浏览器将cookie user="mary17"发送给域”.airtravelbargains.com”中的所有站点:
    Set-cookie: user="mary17"; domain="airtravelbargains.com"
  • 如果用户访问的是www.airtravelbargains.com, specials.airtravelbargains.com或者任意以.airtravelbargains.com结尾的站点, 下列Cookie首部都会发布出去:
    Cookie: user="mary17"

cookie路径属性:

  • cookie规范甚至允许用户将cookie与部分Web站点关联起来。可以通过Path属性来实现这一功能,在这个属性列出的URL路径前缀下所有cookie都是有效的。
  • 例如,某个Web服务器可能是由两个组织共享的,每个组织都有独立的cookie。站点www.airtravelgains.com可能会将部分Web站点用于汽车租赁——比如,http://www.airtravelgains.com/autos/—— 用于一个独立的cookie来记录用户喜欢的汽车尺寸。可能会生成一个如下所示的特殊汽车租赁cookie:
    Set-cookie: pref=compact; domain="airtravelbargains.com"; path=/autos/
  • 如果用户访问http://www.airtravelbargains.com/specials.html, 就会获得两个cookie:
    Cookie: user="mary17"    Cookie: pref=compact
  • 因此,cookie就是由服务器贴到客户端上,由客户端维护的状态片段,只会回送给那些合适的站点

cookie成分:

  • 现在使用的cookie规范有两个不同的版本: cookie版本0(有时被称为Netscape cookies)和cookie版本1(RFC 2965)。cookies版本1是对cookies版本0的扩展, 应用不如后者。
  • cookie规范版本0和版本1都不是作为HTTP/1.1规范的一部分提供的。
  • cookie规范:
标题 描述 位置 持久客户端状态:HTTP cookies 最初的Netscape cookie 标准 http://home.netscape.com/newsref/std/cookie_spec.html RFC 2965:HTTP 状态管理机制 2000年10月的cookie标准, 废弃了RFC2109 http://www.ietf.org/rfc/rfc2965.txt

Session:

  • 正如上面分析的那样,单纯的使用cookie来做用户认证,其实是非常大风险的。因为服务器没有什么手段来判断这个cookie是不是Big-man的真实用户所发送的,很多第三方可以获取到这个cookie,里面的信息就可以被它用来伪造HTTP请求获取Big-man的服务器数据了。所以Big-man需要去寻求新的方法。

引入Session

  • session会话机制。
  • Session一般是指浏览器这个页面打开到关闭的这段时间。所谓的使用session机制其实就是不把用户信息存到浏览器(客户端)而是全部存到服务器上,Big-man只存一个被称为sessionid的值作为cookie存在浏览器端。

session原理:

  • Session原理是服务器端每一个session维护一份会话信息数据,客户端和服务端依靠一个全局唯一标识session_id来访问会话信息数据。用户访问Web应用时,服务端程序决定何时创建session

对于Java后台来说:

  • Session是调用HttpServletRequest.getSession(true)这样的语句时才被创建。这里的Session就是一个Java对象,提供给请求者使用。服务器再次接受到请求的时候就会收到这个Session_id,然后根据ID在内存中找到之前创建的session对象,提供给请求者使用。

不同之处:

  • Session一般放在内存中,一旦服务器重启或者进程停止会被清空。设置了session持久化才能使得重启服务器都能拿到session

Seesion删除时间:

  • (1)、Session超时: 超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。
  • (2)、程序调用HttpSession.invalidate()
  • (3)、服务器关闭或服务停止

关于SessionID:

  • sessionid是从哪里来的,sessionID是如何使用的 : 当客户端第一次请求session对象时候,服务器回味客户端创建一个session,并将通过特殊算出一个sessionID,用来标识该session对象,当浏览器下次(session继续有效时)请求别的资源的时候,浏览器会将sessionID(实质上是cookie)放置到请求头中,服务器接受到请求后就得到该请求的sessionID,服务器找到该idsession返还给请求者(Servlet)使用。一个会话只能有一个session对象,对session来说是只认id不认人
  • 对于Java后台来说,session是一个容器,可以存放会话过程中的任何对象。

安全:

  • Session机制中,数据是存储在服务器上面,所以别人是不可能伪造的,需要获得这些数据就必须使用服务器提供的session_idCookie是保存在客户端的,安全性很难得到保证。
  • 其实Big-man使用session的话session是不会因为浏览器的关闭而删除的。

关于session_id的时效性:

  • 一般来说用session保持持久链接,也就是用户登陆认证通过后,保持对这个用户的识别。但是Big-man的这个登录必须设置一个时效,也就是说登录了一段时间后Big-man要求用户重新登录。
  • 其实也就是设置cookie(session_ID)的有效时间,当超过时了这个session_Id就无效了,Big-man就要再次登录,再次输入认证信息,然后服务器接收这些信息再次生成一个新的session,并把用户认证的信息存入这个session

SessionCookie过期的对比:

首先Cookie过期:

  • Cookie一般有两种,一种是不设置过期时间,浏览器关闭就过期,一种是设置过期时间,存在硬盘中,下次打开浏览器仍然存在。 上面的分析已经提到了。
  • 注意一般来说,cookie过期的话,再次打开浏览器就会被删除了。

再者Session_idsession:

  • Session的话其实主要看session_id,大部分的会话机制是利用session_id(也是cookie),如果cookie过期了也就是session_id过期了,那么显然服务器中的session也会结束生命周期(被销毁)。(如果浏览器没有删除cookie,你发送了一个过期的cookie,服务器需要判断然后就会拒绝你的请求)。

Session过期:

  • session自动失效:一般服务器也会设置Session的过期时间,一旦session过期了,就算客户端的cookie(session_id)没有过期,session照样会结束自己的生命周期。

SessionID如何产生,由谁产生,保存在哪?

创建:

  • 服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequestgetSession方法(使用true作为参数)创建的。

sessionid生成算法:

  • tomcatManagerBase类提供创建sessionid的方法:随机数+时间+jvmid
  • 存储在内存中

如何持久化?

  • cookie memcache redis 存到数据库中
  • 这里有个问题,当服务器遇到大量并发请求的时候怎么解决生成的session_id不重复的问题?

JackDan9 Thinking

原创粉丝点击