Spring Security前置知识3--Cookie与Web Storage

文章目录

  • 一、概述
  • 二、Cookie产生背景
  • 三、Cookie值在哪里设置
  • 四、Cookie有哪些属性
  • 五、Cookie存储在哪里
  • 六、Cookie如何传到后台
  • 七、后台如何处理Cookie
  • 八、Cookie存储空间与数量的限制
  • 九、Web本地存储(Web Storage)
    • 1、Web Storage的产生
    • 2、Web Storage简单介绍
    • 3、Web Storage的问题
    • 4、LocalStorage用于存储Jwt Token

一、概述

  在Session篇说过为了维持Http请求有状态化,需要有“会话”的概念,服务端信息+客户端信息共同协作维持会话。
  其中Cookie是会话在客户端的载体,Session是会话在服务器端的载体。客户端会话存储在浏览器中。服务器端会话存储在Web中间件中。

二、Cookie产生背景

  单论Cookie的产生,网上查是早于Session,当时只是想在浏览器端保存一些网站的设置信息,所以起了这么个名字。理论上登录才是第一需要解决的问题。。。

三、Cookie值在哪里设置

  Cookie的内容由服务器端产生,通过构建Cookie对象,调用Response的setCookie方法设置。或者直接通过Response的addHeader方法来设置,通过Response Header传递给浏览器端。

Cookie cookie = new Cookie("test", "11");
cookie.setPath("/");
cookie.setHttpOnly(true);
response.addCookie(cookie);
// response.addHeader("Set-Cookie", "uid=1123456; Path=/; HttpOnly");

  Cookie也可以在前台通过js设置,一般用于后台不方便设置的时候,如我们在ajax访问中希望在返回结果后增加Cookie。

document.cookie="name="+value;  

四、Cookie有哪些属性

Cookie主要属性是一个键值对name和value,还有其它的附属控制属性。
我们可以查看Java中Cookie的源码

private String name;
private String value;
private String comment;
private String domain;
private int maxAge = -1;
private String path;
private boolean secure;
private int version = 0;
private boolean isHttpOnly = false;

public Cookie(String name, String value) {
    // 构造函数逻辑
}

属性说明:

  1. name和value是必填字段 ,所以Java只提供了一个需要name和value的两参数构造函数。其它的字段事实上除了comment都不会为空。
  2. comment 注释,可选。
  3. domain表示cookie的域。
    默认值
    默认情况下,会自动截取域名作为domain的值,如http://siteA.abc.com/test/index.html会取siteA.abc.com。
    如果有需要,我们也可以可以手动设置domain的值,但是只能设置为上级域名且非顶级域名。
      如果在js中尝试设置进行错误的值,会有特别清楚的报错。下图我们尝试修改pan.baidu.com的域,第一个提示设置的域并不是实际域名的后缀,也就是上级域。第二个不能设置为顶级域。也就是只能设置为自己家的上级域。
    Spring Security前置知识3--Cookie与Web Storage_第1张图片
      如果在java中尝试设置进行错误的值,经过实验,除非格式错误会提示“java.lang.IllegalArgumentException: An invalid domain [.abc.com] was specified for this cookie”,否则并不会提示报错,但是cookie并不能设置成功。

跨域的一种情况
  假设某个公司有两个站点,siteA.abc.com,siteB.abc.com,如果想要相互访问,如siteA中有个Cookie希望能被siteB访问到,无法显式将site设为siteB.abc.com。
可以都将domain设置为父级域名,都设置为abc.com。这在使用单点登录时作为一种简单的处理跨域请求的方法。

  1. path
    默认值
    默认情况下,会截取请求的domain到最后一个斜杠前的路径,作为path,如http://siteA.abc.com/test/a/index.html会取/test/ a/。
    如果有需要,我们可以手动设置path。
    domain和path合成为一个整体路径,表示什么样的请求能够访问Cookie。
    如果path设为test/a,则test/a/路径下的所有子路径都可以访问该Cookie。而test/下的其它路径则无法访问该Cookie。
    注意:
    如果你的Cookie是整站都要使用的,而当前response路径并不是根路径,需要使用setPath("/")手动设置为根路径。

  domain和path的默认值设置逻辑,在java.net包的CookieManager.java下,描述了如何按照RFC 2965文档标准进行的值设置逻辑。
  但是我debug并不会走这里,也没在java代码中找到哪里设置了这俩的默认值,我甚至怀疑这个值是浏览器最终判定与设定的。。。如果有人找到设置默认值的地方,请告诉我。

  1. maxAge
    默认值为-1
    表示Cookie的过期时间,如果Cookie设置了过期时间,Cookie会存储在硬盘中。如果设置Cookie为-1(默认值)或者0,Cookie会在浏览会话结束后删除。
    浏览会话结束的意思是浏览器完全关闭

  2. 不是页面关闭,即使将当前网站的所有页面关掉,设置为maxAge -1的Cookie仍然存活。

  3. 假设浏览器能开启多个,需要浏览器完全关闭,多个只是表现形式而已,事实上只有一个实例开启着。

  4. version
    默认值为0。
    设置Cookie的版本,Cookie Version 0版本中,空格,方括号,圆括号,等于号(=),逗号,双引号,斜杠,问号,@符号,冒号,分号等“特殊”字符都不能作为Cookie的value。新的Cookie Version 1的版本可以使用这些字符,但是尚未被所有浏览器支持,主要是这个改变貌似。。。并没有多么必要。

  5. secure
    默认值为false
    如果设置为true,表示只有https的请求才会去查询这个cookie,否则http和https都可以访问到cookie。如果你修改了请求的方式,可能cookie就查询不到了。
    Cookie存储的时候,相同domain内,会按照协议分成两个大组, http和https,以https://开头的请求,只会取https组里面的Cookie。
    我们会在CA篇中详细讲到https。

  6. httpOnly
    默认值为false
    如果设置为true,意味着只能从ServletRequest中获取Cookie,无法通过JavaScript获取Cookie,是防止XSS攻击的一种手段。

五、Cookie存储在哪里

  Cookie存储在浏览器端,不同的浏览器存储位置不一样 ,无法跨浏览器使用。
浏览器会先按照domain分组,domain内部按协议分组,组内按path分树的方式保存Cookie。这样最方便查询。
  在chrome浏览器中,可以通过设置(chrome://settings/)->高级->内容设置->Cookie->查看所有 Cookie 和网站数据来查看和单独删除某个网站的Cookie。
Spring Security前置知识3--Cookie与Web Storage_第2张图片
  这里面脚本可访问就是httpOnly,到期时间就是maxAge

  在清除浏览器缓存时,如果选择了清除Cookie,那么将会清除掉保存的网站设置,网站账号密码,和当前登录有关的数据JSESSION_ID、JWT、或者其它Token
Spring Security前置知识3--Cookie与Web Storage_第3张图片

六、Cookie如何传到后台

  浏览器发送任何请求的时候,会根据当前请求的domain和path去cookie里面匹配,将匹配到的cookie带在Request Header中去请求数据。

七、后台如何处理Cookie

  后台通过HttpServletRequest的getCookies()方法获取Cookie[]数组,我们需要通过getName来进行匹配,找到我们想用的Cookie。
  传到后台的Cookie中domain和path都为空,只要是浏览器自动带着的,就是浏览器根据当前request的url筛选后的,我们直接使用即可,domain和path没有意义。

八、Cookie存储空间与数量的限制

  Cookie存储有大小与数量的限制,不同浏览器实现不同,大约是每个域名下4k的空间与50个Cookie。

九、Web本地存储(Web Storage)

  Web Storage由于和Cookie的可比性很强,并且内容很简单,我们放到一起说下。

1、Web Storage的产生

  Cookie的特性,导致了另外一种(两种)Web端存储的产生。

  1. 最主要原因是Cookie每次请求必须带着所有Cookies数据,假设需要按条件来决定什么时候该获取什么数据,Cookie不提供这种自由性。
  2. Cookie可以被禁用或者手动清除,会造成数据丢失。
  3. Cookie有限的空间和数量限制。假设有很多的数据需要临时存储,比如很多网页游戏,手机端H5 App都有离线的功能,等能连接网络的时候,再将数据同步上去。这个时候使用Cookie,无论是空间还是数量都无法满足要求。

2、Web Storage简单介绍

  为了解决Web端存储的问题,H5推出了Web Storage。
  有两种Web Storage,LocalStorage和SessionStorage。这两种的唯一区别就是SessionStorage会在浏览器会话结束后清空,这和maxAge为-1的Cookie效果相同。而LocalStorage永久存储,只能通过编程手段删除(当然这并不绝对,并不能阻止你找到LocalStorage的本地存储位置,去删掉)。
  Web Storage通过键值对保存,键值都为String类型,如果你想在键/值中存储复杂对象,需要使用JSON.stringify或者JSON.parse进行序列化与反序列化。
  Web Storage通过同源策略访问,这一点和Cookie差别比较大,Cookie依靠domain和path,如果不限制secure,将能取到http和https的。Web Storage依靠同源,也就是协议+domain+端口。
  Web Storage能够存储5M的数据,并不限制数据条数,足够保存很多应用的离线数据。

3、Web Storage的问题

  Web Storage被设计为Web端的存储介质,作为存储比Cookie有很多优势。但是毕竟只是Web端存储,数据安全性无法保证。这包括两个方面:1、数据并不是绝对不会被删除;2、数据以明文显示,很好获取。
  所以WebStorage只是作为辅助存储的手段,应用在如离线数据等非敏感数据的本地缓存。

4、LocalStorage用于存储Jwt Token

  我们会在Jwt篇横向比较Jwt Token在Web端的存储方式,LocalStorage配合Authorization Header,会是保存Jwt Token的最佳实践。

你可能感兴趣的:(前端)