完全弄懂session,cookie,token

 

session,cookie和token到底是什么

简述

我在写以前看了不少篇session,cookie的文章,有的人说先有了cookie,后有了session。也有人说先有session,后有cookie。感受都没有讲的很清楚,泛泛而谈。但愿本篇文章对你们有所帮助
注:本文须要读者有cookie,session,token的相关基础知识。php

http是一个无状态协议

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

cookie和session

因为http的无状态性,为了使某个域名下的全部网页可以共享某些数据,session和cookie出现了。客户端访问服务器的流程以下web

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

 

 

注意

  • 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 的场景. 所谓无状态就是服务端并不会保存身份认证相关的数据。json

组成

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

存放

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

token认证流程

token 的认证流程与cookie很类似api

  • 用户登陆,成功后服务器返回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,因此提交的表单没法经过服务器过滤,也就没法造成攻击。跨域

分布式状况下的session和token

咱们已经知道session时有状态的,通常存于服务器内存或硬盘中,当服务器采用分布式或集群时,session就会面对负载均衡问题。浏览器

  • 负载均衡多服务器的状况,很差确认当前用户是否登陆,由于多服务器不共享session。这个问题也能够将session存在一个服务器中来解决,可是就不能彻底达到负载均衡的效果。当今的几种解决session负载均衡的方法。

而token是无状态的,token字符串里就保存了全部的用户信息服务器

  • 客户端登录传递信息给服务端,服务端收到后把用户信息加密(token)传给客户端,客户端将token存放于localStroage等容器中。客户端每次访问都传递token,服务端解密token,就知道这个用户是谁了。经过cpu加解密,服务端就不须要存储session占用存储空间,就很好的解决负载均衡多服务器的问题了。这个方法叫作JWT(Json Web Token)

总结

  • session存储于服务器,能够理解为一个状态列表,拥有一个惟一识别符号sessionId,一般存放于cookie中。服务器收到cookie后解析出sessionId,再去session列表中查找,才能找到相应session。依赖cookie
  • cookie相似一个令牌,装有sessionId,存储在客户端,浏览器一般会自动添加。
  • token也相似一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可知道是哪一个用户。须要开发者手动添加。
  • jwt只是一个跨域认证的方案

参考文章

Cookie、Session、Token那点事儿
cookie,token验证的区别
有了cookie为何须要session
CSRF Token的设计是否有其必要性
cookie,token,session三者的问题和解决方案
负载均衡集群中的session解决方案
JWT介绍
Json Web Token 入门教程

谢谢

本文若有错误,欢迎留言讨论

相关文章
相关标签/搜索