session,cookie和token

218 阅读3分钟

http是一个无状态的协议

无状态:这次请求和上次请求没有关系。无状态的好处是快速。

cookie和session

为使某个域名下的所有网页能够共享某些数据出现了session和cookie。
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给客户端。

cookie用途

cookie主要用于:

  • 会话状态管理
  • 个性化设置
  • 浏览器行为跟踪

限制访问cookie

Secure属性 和 HttpOnly属性可以确保cookie被安全发送,并且不会被意外的参与者或脚本访问。

  • 标记为Secure属性的cookie只应通过HTTPS协议加密过的请求发送给服务端,可以预防中间人攻击。
  • Document.cookie API 无法访问带有HttpOnly属性的cookie。此类cookie仅作用于服务器。可以缓解跨站脚本攻击。

问题

  • cookie是实现session的一种方案。禁用cookie还可以通过放在url中等方法存储。
  • 现在大多是Session+Cookie,但是单独使用其中一种也可以保持会话状态。
  • session只需要在客户端保存一个id,大量数据都是保存在服务端。
  • 只用cookie,数据量大的时候,客户端空间不足而且网络传输的数据量也会变大。

token

form发起的post请求不受同源策略的限制,可以任意地使用其他域的cookie向其他域发送post请求造成CSRF攻击。(通过http-only可以禁止js读取和操作cookie).在post请求的瞬间,cookie会被浏览器自动添加到请求头中。但token是开发者为了防范CSRF设计的令牌,浏览器不会自动添加到headers里,攻击者无法访问用户的token,所以提交的表单无法通过服务器过滤,无法形成攻击。

jwt

jwt是token的一种实现方式,是session负载均衡问题的一种解决方案,也是一种跨域认证的方案。基于java web领域的事实标准。组成部分:Header,P session是有状态的,一般存在服务器内存或硬盘中,当服务器采用分布式或者集群时,session会面临负载均衡的问题。 负载均衡多服务器的情况下,不好确认当前用户是否登录,因为多服务器不共享session。将session存在一个服务器中解决该问题就不能完全达到负载均衡的效果。
客户端登录传递信息给服务端,服务端收到后把用户信息加密传给客户端,客户端将token存放于localStroage等容器中。客户端每次访问都传递token,服务端通过cpu加解密token,服务端就不需要存储session占用存储空间,很好地解决了负载均衡多服务器的问题。

总结

  • session存储于服务器,拥有唯一识别符号sessionId,通常存放于cookie中。服务器收到cookie后解析出sessionId,再去session列表中查找,才能找到相应session。需要依赖cookie。
  • cookie类似于一个令牌,装有sessionId,存储在客户端,浏览器通常会自动添加
  • token类似于一个令牌,用户信息都被加密到token中,服务器收到token后解密。需要手动添加。

参考资料