前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【安全】 Cookie

【安全】 Cookie

作者头像
神仙朱
发布2020-02-17 14:54:55
1.3K0
发布2020-02-17 14:54:55
举报

后面会把前端进阶的课程内容都总结一遍。有些都是很常见的知识,但是为了梳理自己的知识树,所以尽量模糊的地方都会记录

笔记列表在公众号右下角

今天就来完整总结一下我们的只是盲点 Cookie,摸摸良心问自己,当别人问你 Cookie 是什么的时候,你真的能很自信地回答出来吗?真的能说的很好吗?

如果你可以的话,就算了哈哈哈

如果你不可以,这才对嘛,这就是我们这篇文章记录的目的了

目的也是完善我们的知识体系,巩固每一个知识点。不要觉得好像简单就忽略,觉得麻烦就不愿意深挖

下面分四块来总结 cookie

1、Cookie 简介

2、Cookie 属性组成

3、Cookie 操作

4、Cookie 的前后端配合

Cookie简介

Cookie 是本地存储的一些数据,存储在本地电脑的文本文件中

Cookie 是后端生成,随着响应发送给浏览器,然后浏览器保存起来。紧接着每次浏览器和该服务器交互都会携带这个 Cookie

Cookie 常用于存储 web 页面的用户信息。因为 http 协议是无状态的,所以无法确定各个访问用户的身份。但是在实际中,必须要确定用户的信息,所以 cookie 就成了 前后端确定用户登录的指标

Cookie 也可以用于记录一些用户操作的信息。比如说用户点击了哪个 tab,用户关闭又打开之后,你可以直接跳到那个 tab,方便用户操作。

Cookie 每个域名下有数量限制(不同浏览器下不一样),并且每个 Cookie 又有大小限制,大约为 4KB,注意是每个 Cookie 容量为 4KB,不是指 所有Cookie 加起来为 4KB,所以 Cookie 通常指存储一些小量信息

Cookie组成

下面我们就来记录一下 Cookie 是由哪些东西组成的!

我们先去浏览器中截个图

你看到这个域名下,有很多个Cookie,其中每个Cookie 又有很多东西组成

打印出这个域名下的 Cookie

咦,怎么是所有 cookie 都拼成一个字符串了,而且只有 name 和 value 属性显示出来

没错!当你获取 cookie 的时候,把 所有的 cookie,按照 键值对,key=value 组成,每个键值对之间由一个分号和一个空格隔开

如下两个 cookie的间隔,有一个 ; 和 一个 空格

而且不会显示其他隐性属性,但是设置新的 cookie 的时候可以设置 这些隐性属性

下面就来说一下所有的属性都是什么东西,按照 Network 的顺序来看,有十个属性,客官慢慢品~

1Name

每一个 cookie 都必须有一个名字,这样才好区分各个cookie,所有这个属性就表示 cookie 的名字

2Value

每一个 cookie 的值,这就是 存储数据的地方,所有存进 cookie 中的数据都放在这个属性里面

name 和 value 是 cookie 的两个主要属性,也是暴露属性,供外部获取,可以通过 document.cookie 拿到

下面就来看一下 cookie 的隐性属性,他们都无法通过 document.cookie 获取

3Domain

设置 Cookie 在哪个域名下可用,所以 Cookie 是不能跨域的。

不能设置成接口外的其他域名

比如说你在域名是 a.com 页面下增加一个cookie,设置domain 为 b.com,那么这个 cookie 是无效的,无法添加

父子域名间访问

二级域名下的 cookie,二级域名以上的网站都可以访问

几个三级域名下的 cookie,是不能相互访问的

什么是二级域名?

.com 是顶级域名、一级域名

baidu.com 是 二级域名

t.baidu.com 是 三级域名

d.t.badiu.com 是 四级域名

也就是说

baidu.com 下有一个 cookie

a.baidu.com , b.baidu.com , c.b.a.baidu.com 都可以获取到这个 cookie

而 a.baidu.com 下的 cookie,b.baidu.com 无法获取到

有点绕,自己理一下不难理解

总的来说

子域名 能 获取到 父域名 下的 cookie

父域名 不能 获取到 子域名 下的 cookie

兄弟级别的域名 不能 相互获取对方 cookie

4Path

设置 cookie 在哪个路径下可用,跟 domain 合成 限制二人组

比如说,如果设置 cookie 只在a.com/course 下生效,就必须设置 path 为 /course

如果不设置,默认就是当前路径,比如说你在 a.com/a/b 下设置 cookie,那么 path 默认就是 /a/b

如果你想整站通用,就设置为 /,表示根目录,该域名下整站通用

5Expires

表示Cookie 的 过期时间,值是一个绝对时间,而且必须是 GMT 格式的时间

什么是 GMT 格式?

就是格林尼治时间,反正通过 new Date 就能拿到了,如下

什么是绝对时间?

就是一个确定的日期时间,比如 2017-09-09,但是是格林尼治时间才可以,如上的截图

如果 expires 设置一个过去的时间,这个 cookie 会马上删掉,差不多就是做一个 然并卵的操作

如果没有设置 expires ,那么默认有效期 是 session,关闭浏览器,cookie 就失效

6Max-Age

和 expires 作用一样,不过这个值的类型是过期的秒数

就是说,你设置了 1000秒,那么在 设置 cookie 1000秒之后,cookie 就会过期

但是这个属性有兼容性问题,ie6,7,8 不支持

7Size

表示这个 cookie 的大小,这里的单位是字节,如下

29 表示29 字节,4095 表示 4095 字节,一个字节就是 1B,所以 4095 字节 也就是约 4 KB

这里的 Size 指的是 name 和 value 加起来 的大小

但是 cookie 的大小 是指 name 和 value 和 等号= 三个加起来

而 一个等号(=) 大小是 1字节

所以通常 Size 的显示 ,是 每个cookie 最大限制减1

比如 火狐 限制每个cookie 最大为 4097 个字节,那么 Size 最多显示为 4096

比如 谷歌 限制每个 cookie 最大为 4096 个字节,那么 Size 最多显示为 4095

关于字节的更多内容可以看这篇文章

【计算机基础】utf6、utf16、utf32

8HTTPOnly

让这个 cookie 不能通过 js 的 document.cookie 获取到。js 无法设置这个属性,只能通过后台来设置

默认情况下,cookie 是不会带 httponly 选项的,也就是为空

9Secure

设置 cookie 只有在https 协议的请求下才发送 cookie,也即是 http 的请求是不会携带 cookie 的

10SameSite

这个的作用是防御 CSRF,但是只有 Google浏览器 存在这个属性

(更多 CSRF 内容,可以看 【安全】CSRF

简单说就是,禁止跨站请求发送cookie

SameSite ,顾名思义就是相同域名,就是,页面发送请求,只有这个请求和页面是同域,那么这个请求才会带上本域名的 cookie,否则不会

举栗子

你已经登录了 b.com,浏览器保存了 b.com 的cookie,当你在 b.com 这个页面下发送 b.com/xxxxx 的请求,都会带上保存的 cookie

如果cookie 没有设置SameSite

你在 a.com 的页面下发送 b.com/xxxx 的请求,这个请求也会带上 b.com 的 cookie,所以会造成 CSRF

如果 cookie 设置了SameSite

那么 a.com 页面下发送 b.com/xxx 的请求,就不会再带上 b.com 的 cookie

不同值不同作用

实际上,SameSite 可以设置不同的值来实现不同的效果,而不是一股脑禁止发送 cookie

SameSite 设置为Strict,就是严格模式,完全禁止跨站发送cookie

SameSite 设置为 Lax,就是宽松模式,如果是 get 请求,可以跨站发送cookie,如果是 post 请求,则不允许跨站发送 cookie

为什么不完全禁止跨站发送cookie?

真的无法禁止,最实际的例子就是,淘宝。

你登陆了淘宝,浏览器保存了 taobao.com 的 cookie

当你从百度或者其他页面点进淘宝的链接进来,此时请求淘宝页面的这个请求不会带上之前你登陆的 cookie,那么你进入淘宝的时候,就是无登录状态,你又要重新登陆,你不是奔溃了??

因为禁止跨站发送cookie 之后,baidu.com 打开 taobao.com ,发送了 taobao.com 的请求,就是跨站了,当然不会带上原来淘宝的 cookie,所以登陆无法统一

Cookie操作

上面讲了那么多 cookie 的属性,现在我们需要来了解 cookie 是怎么操作的

比如说,cookie 如何添加,如何 更新,如何删除

1获取Cookie

应该都知道怎么去获取 cookie 了,就是通过 document.cookie 获取

2添加Cookie

比如要设置一个 名字是 a ,值是 b 的 cookie,操作如下

代码语言:javascript
复制
document.cookie = "a=b"

会不会想,这么做会不会覆盖掉以前的 cookie?

答案是不会,那么这个操作后会发生什么事情?

自动拼接在 原来的 cookie 后面,就是这么神奇

添加其他属性

添加其他属性,expires 之类的时候,需要用 ; 号 隔开,如下

document.cookie = "username=cover"+ ";domain=a.com" + ";expires="+new Date('2018-1-1') + ";secure"

编码

一般我们在添加 cookie 的 时候,需要对 cookie 的 名字和 值 进行编码,主要是为了防止前后端交互时因为乱码而出现错误,比如中文等等

编码使用 JS 内置的方法 encodeURIComponent

然后就这么去操作

代码语言:javascript
复制
document.cookie =
encodeURIComponent ("username")+"=" +encodeURIComponent ('cover')

当然了,拿出来也要记得解码,方法就是 decodeURIComponent

3更新Cookie

更新 Cookie 的 操作 和 添加 Cookie 的操作是一样的

比如之前已经存在一个cookie, 名字是 a ,值是 b ,现在要更新值 为 c,操作如下

代码语言:javascript
复制
document.cookie = "a=c"

看下实操

没错,就是这么简单,如果你要更新其他属性也是可以的,比如你要更新 过期时间 expires

代码语言:javascript
复制
document.cookie= "a=c;expires="+new Date("2019-09-09")

4删除 Cookie

如果你 要删除一个 cookie,直接把 过期时间 expires 设置为 一个过去的时间就可以了,比如是 new Date(0)

比如现在已经存在一个 cookie,我直接更新他的 expires 为过去,然后再获取这个 cookie,就发现为空了,表明已经被删除了

5第三方库 操作 Cookie

是不是发现这么去操作挺麻烦的,我要获取某个cookie 还要手动去截取字符串,删除也是麻烦,所以我们需要封装一个方法去一次性简化我们的操作

但是现在已经有一个现成的 轮子供我们使用了,我们可以拿过来,这个库就是 js-cookie,这个库也很简单,可以看一下源码

地址在这里 https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.js

你看操作起来就十分简单

代码语言:javascript
复制
Cookies.set("name","value",opts) // 添加 cookie

Cookie前后端配合

Cookie 是解决 http 无状态 的一个关键点,利用它实现用户的登录状态,保存用户的信息

实际操作是如下

用户登录之后,服务端返回响应,带上头部

代码语言:javascript
复制
Set-Cookie:id=xxxx

浏览器接收响应,拿到 cookie,保存在浏览器中

在此浏览器发送请求的时候,会自动在请求头部携带上这个 cookie

然后服务端收到请求时,拿到请求携带的 cookie ,就能知道是哪个用户的请求了

最后

鉴于本人能力有限,难免会有疏漏错误的地方,请大家多多包涵, 如果有任何描述不当的地方,欢迎后台联系本人。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 神仙朱 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档