前端数据存储系列(Cookie、Session、localStorage、sessionStorage、Token)

Cookie和Session的联系与区别

简述:
Session比Cookie安全,Session是存储在服务器端的,Cookie是存储在客户端的
背景:
HTTP 是无状态协议,说明它不能以状态来区分和管理请求和响应。也就是说,服务器单从网络连接上无从知道客户身份。
于是想说客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

什么是Cookie(小甜饼?)

Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,实际上Cookie是服务器在本地机器上存储的一小段文本,并随着每次请求发送到服务器。
Cookie会根据响应报文里的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下客户端再向服务端发起请求时,客户端会自动在请求报文中加入Cookie值之后发送出去

保存时间
默认情况下,当浏览器关闭后,Cookie数据被销毁

持久化存储:
setMaxAge(int seconds)
正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
负数:默认值
零:删除cookie信息

应用
cookie一般用于存出少量的不太敏感的数据
在不登录的情况下,完成服务器对客户端的身份识别

缺点
内存小,限制 4KB。数量限制每个浏览器实现不一样,chrome 是 50 个。
默认有跨域限制,不可设置跨域共享 cookie,不可设置跨域传递 cookie

什么是Session

session本意是指客户端与服务器的会话状态,由于凭证存储到了服务端,后来也把这些存在服务端的信息称为session,比如现在服务器决定自己维护登录状态,仅发给客户端一个key,然后在自己维护一个key-value表,如果请求中有key,并且在表中可以找到对应的value,则视为合法。

销毁时间
session什么时候被销毁?

  1. 服务器关闭
  2. session对象调用invalidate() 。
  3. session默认失效时间 30分钟 选择性配置修改
    缺点
    比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效
    同时session还要考虑跨域问题,不过可以使用redis缓存实现,详见 跨域解决了,那Session怎么办

区别

  1. cookie数据存放在客户的浏览器(客户端)上,session数据放在服务器上,但是服务端的session的实现对客户端的cookie有依赖关系的
  2. Session没有数据大小限制,Cookie有
  3. Session数据安全,Cookie相对于不安全
  4. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用COOKIE

联系

session依赖于cookie
服务端执行session机制时候会生成session的id值,这个id值会发送给客户端,客户端每次请求都会把这个id值放到http请求的头部发送给服务端,而这个id值在客户端会保存下来,保存的容器就是cookie,因此当我们完全禁掉浏览器的cookie的时候,服务端的session也会不能正常使用(但是这是在你真的就完全不做任何操作的情况下)。
session不是必须依赖cookie!!!
如果客户端禁用了cookie怎么办呢?
答:

  1. url重写
这种方法让服务器收到的每个请求中都带有sessioinId

在每个页面中的每个链接和表单中都添加名为jSessionId的参数,值为当前sessionid。
当用户点击链接或提交表单时
服务器可以通过获取jSessionId这个参数来得到客户端的sessionId,找到sessoin对象

或者:

使用response.encodeURL()对每个请求的URL处理
这个方法会自动追加jsessionid参数,与上面的手动添加效果是一样的

<a href='<%=response.encodeURL("/jsp/index.jsp") %>' >主页</a>

它更加智能:它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法在URL后面追加jsessionid,否则不会追加。

  1. 表单隐藏字段
服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器
<form name="testform" action="/xxx"> 
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"> 
<input type="text"> 
</form> 

Token

cookie方法不需要服务器存储,但是凭证容易被伪造,那有什么办法判断凭证是否伪造呢?

和HTTPS一样,我们可以使用签名的方式帮助服务器校验凭证。

Token可以避免CSRF攻击

Token可以是无状态的,可以在多个服务间共享

JSON Web Token(简称JWT)是以JSON格式存储信息的Token,其结构图如下

组成

 JWT由3部分构成:头部,负载和签名。

头部存储Token的类型签名算法(上图中,类型是jwt,加密算法是HS256)
负载是Token要存储的信息(比如存储用户姓名和昵称信息)
签名是由指定的算法,将转义后的头部和负载,加上密钥一同加密得到的。

最后将这三部分用.号连接,就可以得到了一个Token了。

使用JWT维护登陆态,服务器不再需要维护状态表,他仅给客户端发送一个加密的数据token,每次请求都带上这个加密的数据,再解密验证是否合法即可。由于是加密的数据,即使用户可以修改,命中几率也很小。

token的储存

一般客户端用以下方式储存token

  1. 存在cookie中,虽然设置HttpOnly可以有效防止XSS攻击中token被窃取,但是也就意味着客户端无法获取token来设置CORS头部。
  2. 存在sessionStorage或者localStorage中,可以设置头部解决跨域资源共享问题,同时也可以防止CSRF,但是就需要考虑XSS的问题防止凭证泄露。

token与cookie的区别

  1. cookie 是 http 规范,token 是自定义传递的。
  2. cookie 没有被浏览器存储(内存是临时存储,关机后信息就没了。硬盘是长久存储,不删除就一直在),下一次请求时便会带上。而 token 需要自己存储在浏览器,下一次请求时再请求头中带上。
  3. token 默认没有跨域限制。
  4. token可以抵抗csrf,cookie+session不行

因为form 发起的 POST 请求并不受到浏览器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域发送 POST 请求,形成 CSRF 攻击。在post请求的瞬间,cookie会被浏览器自动添加到请求头中。但token不同,token是开发者为了防范[CSRF]或XSRF(Cross-site request forgery跨站请求伪造)而特别设计的令牌,浏览器不会自动添加到headers里,攻击者也无法访问用户的token,所以提交的表单无法通过服务器过滤,也就无法形成攻击。

所以:session是比cookie更好的一种解决方案。token成为主流,是因为他不需要额外的存储管理

Web Storage

在 Web Storage 本地存储 包括 sessionStorage 会话存储 和 localStorage 本地存储。
cookie 和 session 完全是服务器端可以操作的数据,sessionStorage 和 localStorage 完全是浏览器端操作的数据。

localStorage与sessionStorage

sessionStorage 和 localStorage 的编程接口是一样的。
sessionStorage 和 locatlStorage 区别在于 数据存在时间范围 和 页面范围。

sessionStorage: 数据只保存到存储它的窗口或标签关闭时,数据在构建它们的窗口或标签内也可见

localStorage: 数据的生命周期比窗口或浏览器的生命周期长,数据可被同源的每个窗口或者标签共享,如果一个浏览器同时打开两个tab,localstorage和cookie是共享的,sessionstorage是不共享的

注意:
localstorage,sessionstorage在浏览器无痕模式下会存在丢失问题

localStorage、sessionStorage、cookie 区别

在这里插入图片描述

参考文章:

Cookie 和 Session 关系和区别
如果客户端禁用了cookie,通常有两种方法实现session而不依赖cookie
session依赖cookie,如果浏览器禁用了cookie呢

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值