Web Cookie

2019-09-11 17:22发布

Web Cookie

什么是Cookie

Cookie是服务器在浏览器保存的一小段文本信息,每个 Cookie 的大小一般不能超过4KB。服务器根据需要通过HTTP Response Headers的Set-Cookie来设置浏览器的Cookie,之后浏览器在向服务器发送请求,就会在HTTP Request Headers的Cookie中带此域名下的Cookie值。我们最常见的Cookie的作用是和服务器端的session结合使用,来在HTTP协议中保存登录后用户的信息。

我们总是说:“当我们在浏览器打开一个网站,就和这个网站建立了会话”。其实这句话的本质是:服务器给浏览器的响应中,向浏览器写入了一个Cookie,这个Cookie的值就session id,这个id用来标识服务器端的一个对象,这个对象就是session对象。

我又总是说:“当我们关闭一个网站,会话结束了,当你再次打开这个网站,会和服务器建立一个新的会话”。这句话的本质是:服务器设置的Cookie生命周期是会话周期,即关闭网站的所有窗口和tab页会话结束,Cookie也就结束了,这个时候服务器的session对象还是存在的,只不过服务器有机制保证session对象在一定的时间未被使用或访问就会销毁这个session对象。当我们在此访问网站,发送第一个请求的时候,服务器的响应一个新的Cookie,即一个新的 session id。

Cookie的格式和属性

通过HTTP Response Headers的Set-Cookie来在浏览器写入Cookie时,此Cookie的格式的每个属性以分号";"进行分割。

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

实际Cookie示例

Set-Cookie:name=zhangxy; Max-Age=86400; Expires=Thu, 12-Sep-2019 03:21:38 GMT; Domain=localhost; Path=/; HttpOnly

value属性
此属性是必须的,它是一个键值对,格式为value=key。上面的示例中key为name,value为zhangxy。
expires属性
expires属性用于指定Cookie过期时间。它的格式采用Date.toUTCString()的格式。
如果不设置该属性,或者设为nul表示Cookie只在当前会话(session)有效,网站的所有窗口或tab页都关闭当前Session就结束了,此时该Cookie就会被删除。如果设置为负数,表明删除该Cookie。如果设置为一个符合格式的时间,表明Cookie的过期时间,浏览器根据本地时间,决定Cookie是否过期,由于本地时间是不精确的,所以没有办法保证Cookie一定会在服务器指定的时间过期。

max-age
max-age属性用来指定Cookie有效期,单位是秒,设置为正整数为Cookie的有效期,设置为负数表示只在当前会话下有效,设置为0表示删除此Cookie,作用等同于expires属性。
max-age是通过设置从现在算起到设置的多少秒之内Cookie有效,expires是通过指定一个时间点,过了这个时间点Cookie失效。比如,当前设置Cookie的max-age属性为60 * 60 * 24 * 365(即一年),当前设置Cookie的时间为2019-09-11,那么此Cookie的到期时间为2020-09-11。和expires设置为2020-09-11效果等同。

expires和max-age属性是设置了Cookie的生命周期,根据生命周期Cookie可以分为内存Cookie和持久化Cookie,前者session结束Cookie也就消失了,后者是即使网站所有tab也关闭了,Cookie信息会写入磁盘,下次在访问此网站,Cookie依然是有效的,直到指定的时间才会失效。

domain属性
指定Cookie所在的域名,比如example.com或.example.com(这种写法将对所有子域名生效)、subdomain.example.com。
如果未指定,默认为设定该Cookie的域名。所指定的域名必须是当前发送Cookie的域名的一部分,比如当前访问的域名是example.com,就不能将其设为google.com。只有访问的域名匹配domain属性,Cookie才会发送到服务器。

path 属性
path属性用来指定路径,必须是绝对路径(比如/、/mydir),如果未指定,默认为请求该 Cookie 的网页路径。
只有path属性匹配向服务器发送的路径,Cookie 才会发送。这里的匹配不是绝对匹配,而是从根路径开始,只要path属性匹配发送路径的一部分,就可以发送。比如,path属性等于/blog,则发送路径是/blog或者/blog/roll,Cookie都会发送。path属性生效的前提是domain属性匹配。

*从domain和path属性可以看出如果需要网站接受Cookie,两个属性必须匹配当前URL路径。例如,当前URL为http://baidu.com/a,那么domain为baidu.com,path为/a(或/a的子路径),此Cookie 才会生效。

secure 属性
secure属性用来指定Cookie只能在加密协议HTTPS下发送到服务器。

HttpOnly属性
设置该Cookie不能被JavaScript读取。通过document.cookie不会返回设置HttpOnly属性的Cookie,即使进行AJAX操作时,XMLHttpRequest对象也无法包括这个Cookie。这主要是为了防止XSS攻击盗取Cookie。注意:XMLHttpRequest对象和js无法读取,不代表浏览器本身不可以,设置了HttpOnly属性的Cookie还是会包含在Request Headers中的。

Cookie的应用场景

我能想到的就两个:

  1. 在Cookie中存储JSESSIONID,用于与服务器端的session对象建立联系。
  2. 在Cookie中存储用户名和密码(应该是加密后的密码),用于用户打开登录页面自动登录系统。

JavaScript中的Cookie对象

通过document.cookie来操作Cookie对象。不做详解,有兴趣百度。

Java中的Cookie对象

Java中通过javax.servlet.http.Cookie来创建一个Cookie对象,通过response.addCookie来向响应中添加一个Cookie对象。

向浏览器中添加名为lsmsAppService-JWT-token的Cookie

//lsmsAppService-JWT-token是value属性的key部分
//token是value属性的value部分
Cookie cookie = new Cookie("lsmsAppService-JWT-token", "token");
cookie.setMaxAge(-1);	//声明周期为会话声明周期
cookie.setDomain("localhost"); 		//域名为localhost
cookie.setPath("/");		//设置路径
cookie.setHttpOnly(true); 	//设置浏览器端JS无法读取此Cookie
response.addCookie(cookie);

在浏览器中删除名为lsmsAppService-JWT-token的Cookie

Cookie cookie = new Cookie("lsmsAppService-JWT-token", "");
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setMaxAge(0); //0标识在浏览器中删除此Cookie
response.addCookie(cookie);

在浏览器中更新名为lsmsAppService-JWT-token的Cookie

Cookie cookie = new Cookie("lsmsAppService-JWT-token", "JWT-token");
cookie.setDomain("localhost");		//同创建lsmsAppService-JWT-token Cookie时的domain值一样
cookie.setPath("/");		//同创建lsmsAppService-JWT-token Cookie时的path值一样
cookie.setMaxAge(60*60*24);
response.addCookie(cookie);

注意:向浏览器写入Cookie时设置的value、domain、path和secure会作为此Cookie的唯一标识,在删除或修改此Cookie时,会匹配创建Cookie时设置的value、domain、path和secure。

参考资料:
https://m.w3cschool.cn/javascript_guide/javascript_guide-yfck269z.html
https://www.cnblogs.com/mao2080/p/9520185.html
https://www.cnblogs.com/bq-med/p/8603664.html

标签: