理解Cookie和Session的区别及使用

h

前言

  • HTTP是一种无状态的协议,为了分辨链接是谁发起的,需自己去解决这个问题。不然有些情况下即使是同一个网站每打开一个页面也都要登录一下。而Session和Cookie就是为解决这个问题而提出来的两个机制。

应用场景

  • 登录网站,今输入用户名密码登录了,第二天再打开很多情况下就直接打开了。这个时候用到的一个机制就是cookie。
  • session一个场景是购物车,添加了商品之后客户端处可以知道添加了哪些商品,而服务器端如何判别呢,所以也需要存储一些信息就用到了session。

1.Cookie

  • 通俗讲,是访问某些网站后在本地存储的一些网站相关信息,下次访问时减少一些步骤。更准确的说法是:Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一服务器,是在客户端保持状态的方案。
  • Cookie的主要内容包括:名字,值,过期时间,路径和域。使用Fiddler抓包就可以看见,比方说我们打开百度的某个网站可以看到Headers包括Cookie,如下:


    BIDUPSID: 9D2194F1CB8D1E56272947F6B0E5D47E
    PSTM: 1472480791
    BAIDUID: 3C64D3C3F1753134D13C33AFD2B38367:FG
    ispeed_lsm: 2
    MCITY: -131:
    pgv_pvi: 3797581824
    pgv_si: s9468756992
    BDUSS: JhNXVoQmhPYTVENEdIUnQ5S05xcHZMMVY5QzFRNVh5SzZoV0xMVDR6RzV-bEJZSVFBQUFBJCQAAAAAAAAAAAEAAACteXsbYnRfY2hpbGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALlxKVi5cSlYZj
    BD_HOME: 1
    H_PS_PSSID: 1423_21080_17001_21454_21408_21530_21377_21525_21193_21340
    BD_UPN: 123253
    sug: 3
    sugstore: 0
    ORIGIN: 0
    bdime: 0


  • key, value形式。过期时间可设置的,如不设,则浏览器关掉就消失了,存储在内存当中,否则就按设置的时间来存储在硬盘上的,过期后自动清除,比方说开关机关闭再打开浏览器后他都会还存在,前者称之为Session cookie 又叫 transient cookie,后者称之为Persistent cookie 又叫 permenent cookie。路径和域就是对应的域名,a网站的cookie自然不能给b用。

2.Session

  • 存在服务器的一种用来存放用户数据的类HashTable结构。
  • 浏览器第一次发送请求时,服务器自动生成了一HashTable和一Session ID来唯一标识这个HashTable,并将其通过响应发送到浏览器。浏览器第二次发送请求会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的HashTable。
    • 一般这个值会有个时间限制,超时后毁掉这个值,默认30分钟。
  • 当用户在应用程序的 Web页间跳转时,存储在 Session 对象中的变量不会丢失而是在整个用户会话中一直存在下去。
  • Session的实现方式和Cookie有一定关系。建立一个连接就生成一个session id,打开几个页面就好几个了,这里就用到了Cookie,把session id存在Cookie中,每次访问的时候将Session id带过去就可以识别了.

区别

  • 存储数据量方面:session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象
  • 一个在客户端一个在服务端。因Cookie在客户端所以可以编辑伪造,不是十分安全。
  • Session过多时会消耗服务器资源,大型网站会有专门Session服务器,Cookie存在客户端没问题。
  • 域的支持范围不一样,比方说a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解决这个问题的办法是JSONP或者跨域资源共享。

session多服务器间共享

  1. 服务器实现的 session 复制或 session 共享,如 webSphere或 JBOSS 在搭集群时配置实现 session 复制或 session 共享.致命缺点:不好扩展和移植。
  2. 利用成熟技术做session复制,如12306使用的gemfire,如常见内存数据库redis或memorycache,虽较普适但依赖第三方.
  3. 将 session维护在客户端,利用 cookie,但客户端存在风险数据不安全,且可以存放的数据量较小,所以将session 维护在客户端还要对 session 中的信息加密。
  4. 第二种方案和第三种方案的合体,可用gemfire实现 session 复制共享,还可将session 维护在 redis中实现 session 共享,同时可将 session 维护在客户端的cookie 中,但前提是数据要加密。

这三种方式可迅速切换,而不影响应用正常执行。在实践中,首选 gemfire 或者 redis 作为 session 共享的载体,一旦 session 不稳定出现问题的时候,可以紧急切换 cookie 维护 session 作为备用,不影响应用提供服务

--------------------- 本文来自 lyf687 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/liyifan687/article/details/80077928?utm_source=copy

 

关闭浏览器再打开,或者说重启浏览器后,网站是否应该自动登录以及如何实现呢?

要回答这个问题,首先要了解session和cookie的概念。基本概念先不说了,直接说重点。

 

Session是一种服务器端的对象,保存在服务器端。 每个session 有一个唯一的session id。 session的超时也是由服务器来控制。比如,在Django的配置中就有一项叫做SESSION_TIMEOUT的用来控制session超时时间。

 

而Cookie是由客户端进行保存的,其中会保存session id这一项,用以记录服务器端的session. 正因为有此一项,我们在关闭浏览器后再打开浏览器,如果cookie仍然记住了之前的session id,就导致可以自动登录。

 

那么cookie什么情况下会记住session id,什么情况下又记不住呢?这就要说到2种cookie:内存cookie和硬盘cookie. 
Cookie分为内存Cookie(也可以说是进程中Cookie)和硬盘Cookie。大部分的session机制都使用进程中Cookie来保存session id,关闭浏览器后这个进程自动消失了,因此Cookie和Cookie中的session id也消失了,再次连接到服务器时无法找到原来的session. 所以,在这种情况下,就是需要再次输入密码登录的。但是保存在硬盘中的cookie却不会丢失session id,所以即使关闭浏览器再打开,也是仍能连得上上一次的session,从而可以自动登录。
又比如说,我们可以在登录时选择“下次自动登录”,例如CSDN的“记住我一周”,或者我们的购物车信息可以在切换不同浏览器时依然可用。这时用到的就是硬盘Cookie,此时,session id将长期保存在硬盘上的Cookie中,直到session失效为止。

 

除了session和cookie,还有一个常见的服务器端配置项,在Django中叫做 SESSION_EXPIRE_AT_BROWSER_CLOSE. 望文生义,看上去将这个配置项设为True,似乎就可以做到“在重启浏览器之后,必须手动输入密码才能登录”了。其实不然。服务器其实并不知道浏览器关闭了没有,所以关闭浏览器时服务器是不会删除session的,也正是这个原因服务器才会设置一个session的失效时间,不然服务器的资源就会被耗尽。所以当session的失效时间到了,服务器便会将相应的session删除。而我们可以在每一次和服务器的交互中,比如REST API请求和应答,都update当前session,比如session.modified = True, 则该session的超时时间会从当前时间点开始重新计算。

有人可能会说,服务器其实有办法知道浏览器关闭了没有。比如,在JS代码中使用window.onclose来监控标签页是否关闭,然后配合 SESSION_EXPIRE_AT_BROWSER_CLOSE = True ,这样就能够在关闭浏览器的时候清除session了。这么做基本能实现目标,但是也有一个较大的问题:因为在一个浏览器中,可能会有多个标签页,它们是属于同一个session的。当一个标签页被关闭后,该session被清除,会导致所有其他标签页都不可用了。这不会是用户希望得到的体验。

回到最初的问题:关闭浏览器再打开,或者说重启浏览器后,网站是否应该自动登录呢?
答:其实目前有许多网站是支持重启浏览器后自动登录的,比如GitHub. 当然也有些是不支持的,比如网银。
如果要在程序中进行控制,该怎么做呢?笔者实验了一些方法,比如设置cookie的过期时间,但似乎没什么用;不过,可以在浏览器中进行控制。
比如,在Chrome的高级设置的Cookie中,有一项叫做“仅将本地数据保留到您退出浏览器为止”,默认是disable的,将其enable即可实现“重启浏览器,不会自动登录”了。Firefox也有类似的设置。但是,设置这个选项也是有很大副作用的,那就是所有网站都无法自动登录了,比如GitHub. 

所以,总结一下,“对于一般网站来说,即使重启浏览器,仍可以自动登录”,这基本是可以接受的。理由有2点:一、许多知名网站就是这么做的(这似乎不是个好理由);二、服务器端对session其实还是有超时时间控制的,常见的为1小时,当然也有数天的。但是,如果想从程序而不是浏览器的角度,比较完美地控制是否自动登录,笔者还没有找到好的办法。

 

[补充 - 2018/02/24]

今天在Django官网上(How to use sessions)看到这么一段话,值得补充在这里:

 

Browser-length sessions vs. persistent sessions

You can control whether the session framework uses browser-length sessions vs. persistent sessions with the SESSION_EXPIRE_AT_BROWSER_CLOSE setting.

By default, SESSION_EXPIRE_AT_BROWSER_CLOSE is set to False, which means session cookies will be stored in users’ browsers for as long as SESSION_COOKIE_AGE. Use this if you don’t want people to have to log in every time they open a browser.

If SESSION_EXPIRE_AT_BROWSER_CLOSE is set to True, Django will use browser-length cookies – cookies that expire as soon as the user closes their browser. Use this if you want people to have to log in every time they open a browser.

This setting is a global default and can be overwritten at a per-session level by explicitly calling the set_expiry()method of request.session as described above in using sessions in views.

Note

Some browsers (Chrome, for example) provide settings that allow users to continue browsing sessions after closing and re-opening the browser. In some cases, this can interfere with theSESSION_EXPIRE_AT_BROWSER_CLOSE setting and prevent sessions from expiring on browser close. Please be aware of this while testing Django applications which have theSESSION_EXPIRE_AT_BROWSER_CLOSE setting enabled.

简单来讲,就是Django官方认为,只要设置了 SESSION_EXPIRE_AT_BROWSER_CLOSE为True,就应该是使得用户一旦关闭浏览器,cookie就会过期,而当用户下次打开浏览器的时候,他们就需要重新登录了。但是同时,Django官方又提醒说,有一些浏览器(比如Chrome)会有设置允许用户在关闭后再打开浏览器的时候再次浏览老的session,这样的话,就使得 SESSION_EXPIRE_AT_BROWSER_CLOSE失去了意义。经笔者测试,IE11似乎也是和这里描述的Chrome具有一样的行为。这些也验证了本博客原文倒数第二段所描述的浏览器设置的问题。

--------------------- 本文来自 执假以为真 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/nirendao/article/details/78898184?utm_source=copy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值