HTTP 协议中的 cookie

2019-05-29
JavaScript
5047

定义

cookie 是存储在浏览器某个文件中的一段key=value字符串

特性

服务端下发响应时,可以在响应头加上Set-Cookie: key= value,告诉浏览器,需要保存哪些cookie

浏览器在发送请求时,会将此域下的所有cookie字符串,放在http请求header中的Cookie字段中,随请求发送给服务端。

因此服务端可以利用cookie的这种性质,保存一些用户特征。

相关属性

1.domain

domain 规定这个cookie在哪些域名下有效,默认取当前host作为domain

2.path

path 规定cookie在此domain下的特殊路由下生效,算是一个细分的属性,一般用不到,默认/,表示全路由生效

3.epires

cookie 的过期时间

  • 是一个绝对时间,时间要转成GMT形式,如果计算机时间大于这个值,浏览器就将此cookie删除。toGMTString();
  • 默认情况下cookie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户退出浏览器后这些值也会丢失。
  • 现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期

4.HttpOnly

js不能拿到这个cookie值,默认为false

5.secure

它是一个布尔值,指定在网络上如何传输cookie,默认是不安全的,通过一个普通的http连接传输

一个完整的cookie写法:

Set-Cookie: token=d19fb4cac474fe008c16575878215558; Domain=webfem.com; Path=/; Expires=Mon, 17 Jun 2019 13:12:36 GMT; HttpOnly

安全规则

1.cookie只能设置到当前域或者当前域名一级域名下,不能设置到其他域名下。

比如, www.webfem.com 页面,cookie只能设置到 www.webfem.com (当前域) 或者 .webfem.com(一级域),不能设置到百度 www.baidu.com 域名下去。

2.浏览器在发送请求是,只发送域名下的cookie,不会发别的域名下的cookie。

比如, 请求www.webfem.com的请求,只会在header的cookie中带上domain是 www.webfem.com (当前域) 或者 .webfem.com(一级域)的cookie。不可能带其他任何domain的cookie。

这两点都是浏览器规定的安全规则。

如何修改

1.在http 的response 头中设置Set-Cookie字段

现在一般的服务端框架都会封装setCookie操作,

比如:

// express
res.cookie(name, value [, options])

// koa
ctx.cookies.set(name, value, [options])

为了体现本质操作,这里写个net模块的应用

require('net').createServer(function(sock) {
    sock.on('data', function(data) {
        sock.write('HTTP/1.1 200 OK\r\n');
        sock.write('Set-Cookie: token=123\r\n')
        sock.write('\r\n');
        sock.write('hello world!');
        sock.destroy();
    });
}).listen(8080, '127.0.0.1');

响应报文

HTTP/1.1 200 OK
Set-Cookie: token=123

hello world!

2.通过js设置cookie

js操作cookie,只能通过document.cookie属性获取,它是一个可读可写的属性。但是设置了http-only 属性的cookie,这个属性就取不到了。具体操作如下:

// get cookie。document.cookie 会返回所有cookie组成的字符串
document.cookie;

// set cookie。 给 document.cookie 赋值,逐一修改原有cookie,而不会全部覆盖
document.cookie = 'sessionid=12323;name=space';

// 删除cookie, 原理:cookie 值设为空,过期时间设一个比现在早的时间
document.cookie = `sessionid=;expires=${new Date('1970-01-01'). toUTCString()}`

js 能拿到cookie,这为前端开发带来的方便,但是,也出现了一些安全隐患,比如通过<script>标签加载的第三方js,就有可能恶意修改本地cookie,所以设置httpOnly是个很好的习惯。

3.在浏览器的开发者工具中设置

以chrome为例,F12 打开开发者工具 -> Application -> Storage -> Cookies。面板如下:

浏览器中查看cookie

在右侧编辑界面,可以轻松设置cookie。注:设置cookie的时候,最好设置个过期时间,不然可能不生效。

参考文档: https://blog.csdn.net/helloliuhai/article/details/18351439