Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

初次接触 Cookie #20

Open
yyzclyang opened this issue Aug 13, 2018 · 0 comments
Open

初次接触 Cookie #20

yyzclyang opened this issue Aug 13, 2018 · 0 comments

Comments

@yyzclyang
Copy link
Owner

什么是 Cookie

Cookie(复数形态Cookies),中文名称为“小型文本文件”或“小甜饼”,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。

这是维基百科对 Cookie 的词条解释,由此我们可以知道,Cookie 其实是一个储存在本地的一个小文件。

Cookie 的起源

早期 Web 开发面临的最大问题之一是如何管理状态。简言之,服务器端没有办法知道两个请求是否来自于同一个浏览器。那时的办法是在请求的页面中插入一个token,并且在下一次请求中将这个token返回(至服务器)。这就需要在form中插入一个包含token的隐藏表单域,或着在URLqurey字符串中传递该token。这两种办法都强调手工操作并且极易出错。

Lou Montulli,那时是网景通讯的一个雇员,被认为在1994年将 “magic cookies” 的概念应用到了 Web 通讯中。他意图解决的是 Web 中的购物车,现在所有购物网站都依赖购物车。他的最早的说明文档提供了一些 Cookies 工作原理的基本信息该文档在 RFC2109 中被规范化(这是所有浏览器实现 Cookies 的参考依据),并且最终逐步形成了REF2965。Montulli 最终也被授予了关于 Cookies 的美国专利。网景浏览器在它的第一个版本中就开始支持 Cookies,并且当前所有 Web 浏览器都支持 Cookies。

Cookie 的特点

服务器通过Set-Cookie响应头设置 Cookie

浏览器得到 Cookie 之后,每次请求都要带上 Cookie,无形中增加了流量

服务器读取 Cookie 就知道登录用户的信息

由于在 HTTP 请求中的 Cookie 是明文传递的,所以安全性成问题,除非用 HTTPS

Cookie 的大小限制在 4KB 左右,对于复杂的存储需求来说是不够用的

除了这些特点之外,还有

不同浏览器的 Cookie 不共享

Windows 的 Cookie 储存在C盘的一个文件夹中

Cookie 可以作假

Cookie 有有效期,一般是20分钟。浏览器可自行设置,后端也可以强制设置有效期

后端可以设置 Cookie 的有效期,是否只允许 HTTPS 链接,是否允许 JS 修改等等

如何设置 Cookie

语法

Set-Cookie: <cookie-name>=<cookie-value> 
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax

在 Cookie 的设置中,后面的选项是可选的,且可同时多选。

  • 解释

<cookie-name>=<cookie-value>

<cookie-name> 可以是除了控制字符 (CTLs)、空格 (spaces) 或制表符 (tab)之外的任何 US-ASCII 字符。同时不能包含以下分隔字符: ( ) < > @ , ; : \ " / [ ] ? = { }。

<cookie-value> 是可选的,如果存在的话,那么需要包含在双引号里面。支持除了控制字符(CTLs)、空格(whitespace)、双引号(double quotes)、逗号(comma)、分号(semicolon)以及反斜线(backslash)之外的任意 US-ASCII 字符。

Expires=<date>

Cookie 的最长有效时间,形式为符合 HTTP-date 规范的时间戳。如果没有设置这个属性,那么表示这是一个会话期 Cookie 。一个会话结束于客户端被关闭时,这意味着会话期 Cookie 在彼时会被移除。

Max-Age=<non-zero-digit>

在 Cookie 失效之前需要经过的秒数。一位或多位非零(1-9)数字。

Domain=<domain-value>

指定 Cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)。

Path=<path-value>

指定一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。

Secure

一个带有安全属性的 Cookie 只有在请求使用 SSL 和 HTTPS 协议的时候才会被发送到服务器。然而,保密或敏感信息永远不要在 HTTP Cookie 中存储或传输,因为整个机制从本质上来说都是不安全的,比如前述协议并不意味着所有的信息都是经过加密的。

HttpOnly

设置了 HttpOnly 属性的 Cookie 不能使用 JavaScript 经由 Document.cookie 属性、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击(XSS)。

SameSite=StrictSameSite=Lax

允许服务器设定一则 Cookie 不随着跨域请求一起发送,这样可以在一定程度上防范跨站请求伪造攻击(CSRF)。

用法

response.setHeader('Set-Cookie', `sign_in_email=${email}`)

当我们模拟登陆时,就可以看到响应头里面的 Cookie

同样,在跳转网站请求头中也可以看到这个 Cookie

  • 利用JavaScript来修改Cookie

如果没有设置不允许修改 Cookie 的话,是可以利用 JavaScript 来修改 Cookie

document.cookie="sign_in_email=789@yyzcl.com"

此时刷新页面看看

此时可以看到,Cookie 被 JavaScript 修改了

但可以通过设置禁止 JavaScript 来修改 Cookie

response.setHeader('Set-Cookie', `sign_in_email=${email}; HttpOnly`)

这样就无法通过 JavaScript 来修改 Cookie

但是还是可以手动地来修改

再刷新页面看看

Cookie是可以人为地伪造地,所以说 Cookie 是不安全的

设置过期时间

可以通过 Cookie 的以下属性来设置过期时间。

Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
  • Expires指定了一个日期/时间, 在这个日期/时间之后 Cookie 过期

  • max-age指定了一个秒数,经过此秒数后 Cookie 过期

  • 如果不设置这个标头,则默认关闭浏览器后 Cookie 过期

删除 Cookie

有多种方式来删除 Cookie。

  • 服务器可以通过Expiresmax-age这两个标签将� Cookie 设置成过期的状态,之后浏览器会自动清除

  • JavaScript 可以通过document.cookie来操作 Cookie 删除

  • 可以通过浏览器手动删除

后话

我也是接触 Cookie 不久,对其还不是很熟悉,还有很多地方值得去探讨

@yyzclyang yyzclyang changed the title 2018.07.23 初次接触 Cookie 初次接触 Cookie Aug 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant