简介

如果小伙伴最近有访问国外的一些标准网站的话,可能经常会弹出一个对话框,说是本网站为了更好的体验和跟踪,需要访问你的cookies,问你同意不同意,对于这种比较文明的做法,我一般是点同意的。

但是转头一想,为什么访问国内的网站从来没有弹出过这个提示呢?这是一个值得深思的问题,或许当你看完这篇文章之后,就有了答案。

cookies的作用

那么cookies有什么作用呢?HTTP cookies就是服务器端发送给浏览器端的一小部分数据,浏览器接收到这个数据之后,可以存起来自己用,也可以在后续发送到server端进行一些数据的校验。

通过在cookies中存储一些有用的数据,可以将无状态的HTTP协议变成有状态的session连接,或者用来保存登录的权限,下次不用密码即可登陆,非常有用。

一般来说,cookies用在三个方面:

  1. session的管理,用来保存登录状态,从而让HTTP请求可以带上状态信息。
  2. 用户自定义的设置,这些用户特殊的字段,需要保存在cookies中。
  3. 跟踪用户的行为信息。

在很久很久以前,还没有现代浏览器的时候,客户端的唯一存储就是cookies,所以cookies也作为客户端存储来使用的,但是有了现代的浏览器之后,一般是建议把客户端存储的数据放到其他存储方式中。

为什么呢?

因为每次请求cookies中的数据会自动带上,并且发送到server端,所以如果cookies中存储了太多的数据,就会导致服务器性能的下降。

创建cookies

因为cookies是客户端的本地存储,所以如果服务器端想要设置客户端的cookies时,通过在响应头中设置Set-Cookie,浏览器接收到这个响应头之后,就会将对应的cookies内容存储到浏览器本地。

然后在后续的服务器请求中都会带上Cookie header。同时cookie还可以带上过期时间、发送限制等属性。

先来看下Set-Cookie的格式:

Set-Cookie: <cookie-name>=<cookie-value>

举个例子,下面是一个server端的响应:

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: name=flydean
Set-Cookie: site=www.flydean.com

当浏览器接收到这个响应之后,就会在本地的cookies中设置对应的值,并且在后续的请求中将这些值以cookies的header形式带上:

GET /test.html HTTP/2.0
Host: www.flydean.com
Cookie: name=flydean; site=www.flydean.com

在netty中提供了一个Cookie的类,专门用来表示cookies,这个类中提供了cookies的基本属性,然后通过使用:

response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));

来对响应头进行设置。

cookies的生存时间

HTTP的cookies有两种,一种是session cookies,这种cookies会在session结束之后自行删除。

还有一种cookies通过指定Expires或者 Max-Age 来设置过期时间:

Set-Cookie: id=abcdef; Expires=Thu, 31 May 2021 08:00:00 GMT;

其中Expires是HTTP1.0中定义的header,Max-Age是HTTP1.1中定义的header。

cookies的权限控制

HTTP提供了两个属性来对cookies的权限进行控制,分别是Secure和HttpOnly。

如果cookies中带有Secure属性,那么cookies只会在使用HTTPS协议的时候发送给服务器。如果使用的是HTTP协议,则不会发送cookies信息。

并且,如果是在http的情况下,server端是不允许给cookie设置Secure属性的。

但是设置了Secure属性并不意味着cookies就是安全的,因为可以从其他的手段拿到浏览器端的cookies。

还有一个属性是HttpOnly,如果cookies设置了HttpOnly,那么cookies是不允许被JavaScript访问的,通过设置HttpOnly,我们可以提升客户端数据的安全性:

Set-Cookie: id=abcdef; Expires=Thu, 21 May 2021 08:00:00 GMT; Secure; HttpOnly

cookies还可以添加Domain和Path属性,用于标记cookies可以发送到的URL。

其中Domain表示域名,而Path表示路径。

如果Domain没有设置,则默认是设置cookies的host,这个host是不包含子domain的。如果手动指定了Domain,那么子domain是会包含在内的。

比如如果我们设置了Domain=flydean.com,那么子domain:doc.flydean.com也会共享这个cookies。

Path用来匹配URL的路径,只有匹配到的URL才可以发送cookies。

另外HTTP还提供了一个SameSite属性,表示如果是在CORS环境情况下,是否发送cookies到第三方网站,这样可以在一定程度上保护网站的信息。

SameSite有三个可能的值,分别是Strict, Lax, 和 None。如果在Strict情况下,那么cookie仅发送到与创建它的站点相同的站点。Lax跟Strict类似,不同之处在于当用户导航到cookie的原始站点时发送cookie,比如通过访问外部站点的链接。 None可以在原始网站和跨站资源访问中使用,但是必须要在安全的环境中进行(设置Secure属性)。如果没有设置SameSite,那么表现是和Lax一致的。

例如:

Set-Cookie: name=flydean; SameSite=Strict

第三方cookies

我们知道cookies是和domain相关的,如果cookies的domain是和当前访问的页面相同的话,这个cookies就叫做 first-party cookies。如果和当前的访问页面不同,比如访问第三方的图片、脚本、css等,第三方的服务器有可能会发送他们自己的cookies,这种cookies叫做第三方cookies,第三方cookies主要被用来广告或者跟踪用户的行为信息。

对于有些浏览器来说,可能会禁用第三方的cookies,这有可能会导致访问网站的一些功能问题,大家可以主要观察一下。

总结

使用cookies可以辅助我们做很多事情,但是也要注意cookies的安全性。

本文已收录于 http://www.flydean.com/05-http-cookie/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

HTTP系列之:HTTP中的cookies的更多相关文章

  1. 浏览器扩展系列————在WPF中定制WebBrowser快捷菜单

    原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/book ...

  2. 20.翻译系列:Code-First中的数据库迁移技术【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/migration-in-code-first.aspx EF 6 Code-First ...

  3. 8.翻译系列: EF 6中配置领域类(EF 6 Code-First 系列)

    原文地址:http://www.entityframeworktutorial.net/code-first/configure-classes-in-code-first.aspx EF 6 Cod ...

  4. 10.翻译系列:EF 6中的Fluent API配置【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/fluent-api-in-code-first.aspx EF 6 Code-Firs ...

  5. python基础系列教程——Python中的编码问题,中文乱码问题

    python基础系列教程——Python中的编码问题,中文乱码问题 如果不声明编码,则中文会报错,即使是注释也会报错. # -*- coding: UTF-8 -*- 或者 #coding=utf-8 ...

  6. iOS流布局UICollectionView系列七——三维中的球型布局

      摘要: 类似标签云的球状布局,也类似与魔方的3D布局 iOS流布局UICollectionView系列七——三维中的球型布局 一.引言 通过6篇的博客,从平面上最简单的规则摆放的布局,到不规则的瀑 ...

  7. 【iOS系列】-oc中特有的语法

    [iOS系列]-oc中特有的语法 oc数据类型: 1,基本类型 2,对象类型 3,id 4,BOOL 5,block 6,SEL 1:category 使用继承关系来扩充一个类,有一个弊病,高耦合性 ...

  8. shell编程系列1--shell脚本中的变量替换

    shell编程系列1--shell脚本中的变量替换 变量替换总结: .${变量#匹配规则} # 从头开始匹配,最短删除 .${变量##匹配规则} # 从头开始匹配,最长删除(贪婪模式) .${变量%匹 ...

  9. 告诉你:DOS系统实例手册系列专辑连载中

    DOS系统实例手册系列专辑连载中 内容提要:

随机推荐

  1. 记一次系统崩溃事件【Mac版】

    事件:Mac系统崩溃,导致电脑数据丢失,以及数据安全备份措施的不到位的教训! 解决措施: 1.开机后按:Command+R 按开机键 ,进入Mac 实用工具, 选择磁盘工具.由于没有备份直接抹掉磁盘. ...

  2. Spring WebFlow 远程代码执行漏洞(CVE-2017-4971)

    影响版本 Spring WebFlow 2.4.0 - 2.4.4 访问id为1的酒店http:/ :8080/hotels/1,点击预订按钮"Book Hotel",填写相关信息 ...

  3. WebRTC 用例和性能

    WebRTC 用例和性能 实现低延迟.点对点传输是一项艰巨的工程挑战:有 NAT 遍历和连接检查.信令.安全.拥塞控制和无数其他细节需要处理.WebRTC 代表我们处理以上所有内容,这就是为什么它可以 ...

  4. java小程序之随机任务发布器

    需求 自定义任务 随机定时 随机排序 集合输出 搭建 简单项目,所以我使用java 的maven来搭建一个控制台程序,并且使用excel来记录任务 创建任务类(sub) package com.mic ...

  5. 学习mybatis框架>从零开始学JAVA

    目录 学习mybatis框架 mybatis框架的介绍 什么是mybatis框架 为什么要使用mybatis框架 mybatis的优点 Mybatis框架环境搭建 去官网下载jar包 创建一个普通的j ...

  6. House_of_orange 学习小结

    House_of_orange学习小结 house_of_orange最早出现在2016年hitcon的一道同名题目,其利用效果,是当程序没有free函数的时候,我们可以通过一些方法,来让chunk被 ...

  7. 从Python到Go:初学笔记

    本文记录了我在学习Go的过程时的一些笔记,主要是比较Python和Go之间的差异并作简单描述,以此使Python程序员对Go语言的特性有简略的了解.初学难免有纰漏,欢迎各位批评指正补充交流,谢谢. 数 ...

  8. appium自动化测试(5)-一些pyhon操作

    1.套件的问题 将所有的测试用例加进去,会一个个执行,用于用例名字没有规范test开头的时候 def suite(): suite = unittest.TestSuite suite.addTest ...

  9. javaSE基础之变量,常量,作用域和运算符

    变量 变量是什么? 变量是可以变化得量 Java是一种强类型语言,每个变量都必须声明其类型. Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域 type varName [=v ...

  10. C++STL—string类

    string容器 1.1 string容器的基本概念 string容器是一个类 这个容器中有一个指针,指针维护了一个数组 string容器提供copy.find.insert.replace等等功能 ...