cookie,session,localStorage和sessionStorage

前言

http是一个无状态协议。什么是无状态呢?就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。这种无状态的的好处是快速。坏处是假如我们想要把www.zhihu.com/login.htmlwww.zhihu.com/index.html关联起来,必须使用某些手段和工具。

Cookie

Cookie是小甜饼的意思,主要有以下特点:

  • 顾名思义,Cookie 确实非常小,它的大小限制为4KB左右
  • 主要用途是保存登录信息和标记用户(比如购物车)等,不过随着localStorage的出现,现在购物车的工作Cookie承担的较少了
  • 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效
  • 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
  • 原生API不如storage友好,需要自己封装函数
API用法

服务端向客户端发送的cookie(HTTP头,不带参数):
Set-Cookie: <cookie-name>=<cookie-value> (name可选)

服务端向客户端发送的cookie(HTTP头,带参数):
Set-Cookie: <cookie-name>=<cookie-value>;(可选参数1);(可选参数2)

客户端设置cookie:

document.cookie = "<cookie-name>=<cookie-value>;(可选参数1);(可选参数2)"

可选参数:
Expires=<date>:cookie的最长有效时间,若不设置则cookie生命期与会话期相同

Max-Age=<non-zero-digit>:cookie生成后失效的秒数

Domain=<domain-value>:指定cookie可以送达的主机域名,若一级域名设置了则二级域名也能获取。

Path=<path-value>:指定一个URL,例如指定path=/docs,则”/docs”、”/docs/Web/“、”/docs/Web/Http”均满足匹配条件

Secure:必须在请求使用SSL或HTTPS协议的时候cookie才回被发送到服务器

HttpOnly:客户端无法更改Cookie,客户端设置cookie时不能使用这个参数,一般是服务器端使用

示例:

Set-Cookie: sessionid=aes7a8; HttpOnly; Path=/

document.cookie = "KMKNKK=1234;Sercure"

可选前缀:
__Secure-:以__Secure-为前缀的cookie,必须与secure属性一同设置,同时必须应用于安全页面(即使用HTTPS)

__Host-:以__Host-为前缀的cookie,必须与secure属性一同设置,同时必须应用于安全页面(即使用HTTPS)。必须不能设置domian属性(这样可以防止二级域名获取一级域名的cookie),path属性的值必须为”/“。

前缀使用示例:

Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/

document.cookie = "__Secure-KMKNKK=1234;Sercure"
document.cookie = "__Host-KMKNKK=1234;Sercure;path=/"

Session

Session是在无状态的HTTP协议下,服务端记录用户状态时用于标识具体用户的机制。它是在服务端保存的用来跟踪用户的状态的数据结构,可以保存在文件、数据库或者集群中。在浏览器关闭后这次的Session就消失了,下次打开不再拥有这个Session。其实并不是Session消失了,而是Session ID变了,服务器端可能还是存着你上次的Session ID及其Session 信息,只是他们是无主状态,也许一段时间后会被删除。大多数的应用都是用Cookie来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在Cookie里面记录一个SessionID,以后每次请求把这个会话ID发送到服务器

cookie和session的工作原理

由于http的无状态性,为了使某个域名下的所有网页能够共享某些数据,session和cookie出现了。客户端访问服务器的流程如下:

  • 首先,客户端会发送一个http请求到服务器端。
  • 服务器端接受客户端请求后,建立一个session,并发送一个http响应到客户端,这个响应头,其中就包含Set-Cookie头部。该头部包含了sessionId。Set-Cookie格式如下:
    Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
  • 在客户端发起的第二次请求,假如服务器给了set-Cookie,浏览器会自动在请求头中添加cookie
  • 服务器接收请求,分解cookie,验证信息,核对成功后返回response给客户端


    image.png
cookie和session的区别
  • Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中,Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
  • Cookie安全性一般,他人可通过分析存放在本地的Cookie并进行Cookie欺骗。在安全性第一的前提下,选择Session更优。重要交互信息比如权限等就要放在Session中,一般的信息记录放Cookie就好了。
  • 单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie
  • 当访问增多时,Session会较大地占用服务器的性能。考虑到减轻服务器性能方面,应当适时使用Cookie
  • Session的运行依赖Session ID,而Session ID是存在 Cookie 中的。也就是说,如果浏览器禁用了Cookie,Session也会失效(但是可以通过其它方式实现,比如在url中传递Session ID,即sid=xxxx)
838172_1501942685861_37B4C735DA0DFFCC398F8BEBB1CEE5AE.png
注意:
  • cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中
  • 现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用
    用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。
  • 如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大
  • 简而言之, session 有如用户信息档案表, 里面包含了用户的认证信息和登录状态等信息. 而 cookie 就是用户通行证

token

token 也称作令牌,由uid+time+sign[+固定参数]
token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景. 所谓无状态就是服务端并不会保存身份认证相关的数据。

组成

uid: 用户唯一身份标识
time: 当前时间的时间戳
sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库

存放

token在客户端一般存放于localStorage,cookie,或sessionStorage中。在服务器一般存于数据库中

token认证流程

token 的认证流程与cookie很相似

  • 用户登录,成功后服务器返回Token给客户端。
  • 客户端收到数据后保存在客户端
  • 客户端再次访问服务器,将token放入headers中
  • 服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码
token可以抵抗csrf,cookie+session不行

假如用户正在登陆银行网页,同时登陆了攻击者的网页,且银行网页未对csrf攻击进行防护。攻击者可以在网页放一个表单,该表单提交src为http://www.bank.com/api/transfer,body为count=1000&to=Tom。倘若是session+cookie,用户打开网页的时候就已经转给Tom1000元了。因为form 发起的 POST 请求并不受到浏览器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域发送 POST 请求,形成 CSRF 攻击。在post请求的瞬间,cookie会被浏览器自动添加到请求头中。但token不同,token是开发者为了防范csrf而特别设计的令牌,浏览器不会自动添加到headers里,攻击者也无法访问用户的token,所以提交的表单无法通过服务器过滤,也就无法形成攻击。

localStorage和sessionStorage

两者的共同点:
  • 存储大小均为5M左右
  • 都有同源策略限制
  • 仅在客户端中保存,不参与和服务器的通信
两者的不同点:

1、生命周期 —— 数据可以存储多少时间

  • localStorage: 存储的数据是永久性的,除非用户人为删除否则会一直存在。
  • sessionStorage: 与存储数据的脚本所在的标签页的有效期是相同的。一旦窗口或者标签页被关闭,那么所有通过 sessionStorage 存储的数据也会被删除。
    2、作用域 —— 谁拥有数据的访问权
  • localStorage: 在同一个浏览器内,同源文档之间共享 localStorage 数据,可以互相读取、覆盖。
  • sessionStorage: 与 localStorage 一样需要同一浏览器同源文档这一条件。不仅如此,sessionStorage 的作用域还被限定在了窗口中,也就是说,只有同一浏览器、同一窗口的同源文档才能共享数据。

为了更好的理解sessionStorage,我们来看个例子:
例如你在浏览器中打开了两个相同地址的页面A、B,虽然这两个页面的源完全相同,但是他们还是不能共享数据,因为他们是不同窗口中的。但是如果是一个窗口中,有两个同源的iframe元素的话,这两个iframe的 sessionStorage 是可以互通的。

API
//sessionStorage用法相同
localStorage.setItem("name",1);   // 以"x"为名字存储一个数值
localStorage.getItem("name");     // 获取数值
localStorage.key(i);              // 获取第i对的名字
localStorage.removeItem("name");  // 获取该对的值
localStorage.clear();             // 全部删除
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342