2019.7.18 晨讲

  • 2019-07-17
  • 39
  • 0

cookie和session

(计网模型)

一:Http无状态协议

1.1定义:

HTTP无状态协议,是指协议对于交互性场景没有记忆能力。

1.2举个例子:

在点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都会返回同样的信息,因为这个是没有交互的,每一次的请求都是相互独立的。第一个请求和第二个请求也没有先后顺序,返回处理哪个,结果都是同样的资源页面,因为这种场景是无交互的,无论是什么人请求这个地址,服务器都是返回那个相同的响应。

在无交互场景中上面那样,当然也不会有太大的问题。但是对于涉及到动态交互的场景,就显得很尴尬了,何为交互?有来又有往,对于一模一样的两个接口,不同的人在请求第二个接口时可能会基于请求第一个接口的结果而有所不同。

1.3具体场景:

现在我们来想一个复杂的场景,如在购物网站上买电脑,流程如下:

  1. 输入账号密码登陆 /login 用户信息
  2. 选择一款你喜欢的书包加入到购物车中 /cart 用户信息,产品信息
  3. 购买支付 /pay 用户信息,商品信息,金额信息

所谓的登录只是验证你是否是一个合法用户,若是合法则跳转到信息的页面,不合法则告知用户名密码错误。

但是我们在第一步给服务器发完/login接口后,服务器就忘记了。。。忘记了你这个人,到底有没有经过认证。

所以在添加商品时/cart 你还是需要将你的账号密码和商品信息一起提交给 addCart接口,再让服务器做验证。

第三步同理。

1.4存在的问题:

所以我们说涉及到交互时,情形就完全不一样了,因为这三步是有依赖关系的,第一步验证登录者是一个合法用户,验证通过给你返回200/OK,但是只要服务器给返回了响应,那么一个http的请求和响应就结束了。服务器怎么知道10秒钟之前你刚刚登录过呢?不好意思,服务器不知道你有没有登陆过,他只是对外提供一个登录接口,要想证明你是合法用户必须调/login接口。

第二步,将商品加入到购物车中时,你会调用/cart接口,但是注意,这个行为是和第一步是有关联关系的,是谁将什么物品加入到购物车中了?这个谁,有没有在网站上注册账号呢,是不是一个合法用户呢?所以说在添加购物车的时候,我们还需要将账号密码再次加入到请求参数中,每做一次操作购物车操作时,都需要再把之前已经传输过的账号密码,再反反复复的传输一遍又一遍,这是因为服务器不知道你是不是在20秒之前刚登陆过。

1.5总结:

上面的无状态是指的,无登录状态,即服务器不知道某个用户是否已登录过了。因为愚蠢的服务器不知道客户端是否已登录过了,所以每次都要在交互场景(会话)中请求中带上上一次的请求信息,如账号、密码。明明只需要在/login接口中,才需要对比数据库中的账号密码和客户端传的是否一致来确定合法性。这下在添加购物车中也需要再一次的进行同样的重复且没有必要的操作,即降低了响应速度,又对用户不友好(因为每次都需要填账号,密码)。

缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另外人们常说的“会话”概念则是上面的交互行为的另一种表述方式。

二.cookie

由于HTTP是一种无状态的协议,服务器单纯从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。 

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

 Cookie是不可跨域名的

2.1、cookie特点:会话数据保存在浏览器客户端。

2.2、cookie技术核心

cookie类:用于存储会话数据

1)构造Cookie对象

  new  Cookie(java.lang.Stringname, java.lang.String value)

2)设置cookie

   void setPath(java.lang.String uri)   :设置cookie的有效访问路径

   void setMaxAge(int expiry) : 设置cookie的有效时间

   void setValue(java.lang.String newValue) :设置cookie的值

3)发送cookie到浏览器端保存

   void response.addCookie(Cookie cookie)  : 发送cookie

4)服务器接收cookie

  Cookie[] cookies =request.getCookies()  : 接收cookie

2.3:cookie原理

1)服务器创建cookie对象,把会话数据存储到cookie对象中。

     new Cookie("name","value");

2) 服务器发送cookie信息到浏览器

    response.addCookie(cookie);

    举例: set-cookie:name=eric  (隐藏发送了一个set-cookie名称的响应头)

3)浏览器得到服务器发送的cookie,然后保存在浏览器端。

4)浏览器在下次访问服务器时,会带着cookie信息

   举例: cookie: name=eric (隐藏带着一个叫cookie名称的请求头)

5)服务器接收到浏览器带来的cookie信息

   request.getCookies();

2.4:cookie的细节

1)void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。

2)void setMaxAge(int expiry) : 设置cookie的有效时间。

    正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。

    负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!

     零:表示删除同名的cookie数据

3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

三.session

  • Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
  • 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
  • 如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。
  • Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

Session和Cookie的关系

  • cookie 是一个实际存在的、具体的东西,http 协议中定义在 header 中的字段。
  • session 是一个抽象概念、开发者为了实现中断和继续等操作,将client和server之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。
  • 即session描述的是一种通讯会话机制,而cookie只是目前实现这种机制的主流方案里面的一个参与者,它一般是用于保存session ID。

3.1、使用session的优势

经过上面了解到cookie的局限

1)Cookie只能存字符串类型。不能保存对象

2)只能存非中文。

3)1个Cookie的容量不超过4KB。

3.2、session核心

HttpSession类:用于保存会话数据

1)创建或得到session对象

   HttpSession getSession() 

   HttpSession getSession(booleancreate) 

2)设置session对象

   void setMaxInactiveInterval(intinterval)  :设置session的有效时间

    void invalidate()     :销毁session对象

    java.lang.String getId()  :得到session编号

3)保存会话数据到session对象

    void setAttribute(java.lang.Stringname, java.lang.Object value)  :保存数据

    java.lang.ObjectgetAttribute(java.lang.String name)  :获取数据

    voidremoveAttribute(java.lang.String name) :清除数据

3.3、session原理

1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID

    newHttpSession();

2)把JSESSIONID作为Cookie的值发送给浏览器保存

     Cookiecookie = new Cookie("JSESSIONID", sessionID);

    response.addCookie(cookie);

3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器

4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。

                                        if(找到){

                                                 returnmap.get(sessionID);

                                        }

                                        Map<String,HttpSession>

                                        <"s001",s1>

                                        <"s001,"s2>

5)如果找到对应编号的session对象,直接返回该对象

6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程

结论:通过JSESSION的cookie值在服务器找session对象!!!!!

3.4、session细节

1)java.lang.String getId() :得到session编号

2)两个getSession方法:getSession(true)/ getSession() : 创建或得到session对象。没有匹配的session编号自动创建新的session对象。

getSession(false): 得到session对象。没有匹配的session编号,返回null

3)void setMaxInactiveInterval(int interval) : 设置session的有效时间

默认情况30分服务器自动回收

Cookie与Session的区别

Cookie数据存放在客户端,用来记录用户信息的,Session数据存放在服务器上。
Cookie安全性不够。正式由于Cookie存储在客户端中,对客户端是可见的,客户端的一些程序可能会窥探、复制甚至修改Cookie中的内容,并进行Cookie欺骗。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的危险,因此较为安全。如果选用Cookie,比较好的办法是,敏感的信息如账号密码等尽量不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只有自己能读得懂。而如果选择Session就省事多了,反正是放在服务器上,Session里任何隐私都可以。
Session是保存在服务器端的,每个用户都会产生一个Session。如果并发访问的用户非常多,会产生非常多的Session,消耗大量的服务器内存。因此像 Google、Baidu这样并发访问量极高的网站,是不太可能使用Session来追踪客户会话的。Cookie性能更高一些,因为Cookie保存在客户端,不占用服务器资源。如果并发浏览的用户非常多,Cookie是很好的选择。
Cookie的容量和个数都有限制。单个Cookie的容量不能超过4KB,很多浏览器都限制一个站点最多保存20个Cookie,而Session没有此问题。

评论

还没有任何评论,你来说两句吧