第一章 了解 Web 及网络基础
使用 HTTP 协议访问 Web
当我们在浏览器地址输入 URL 敲下回车,根据 Web 浏览器地址栏中指定的URL,Web 浏览器从 Web 服务器端获取文件资源(resource)等信息,从而显示出 Web 页面。
从客户端到服务器端等一系列运作流程,使用的就是HTTP协议。
Web 是建立在 HTTP 协议上通信的。
HTTP 的诞生
1989年3月,HTTP 诞生了。
CERN(欧洲核子研究组织)的蒂姆 • 伯纳斯 - 李(Tim BernersLee)- 李爵士
提出了3项 WWW 构建技术
- HTML
- HTTP
- URL
网络基础 TCP/IP
通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作的。而 HTTP 属于它内部的一个子集。
计算机与网络设备要相互通信,双方就必须基于同样的方法,遵守同样的规则,这个规则就叫做协议。
互联网相关联的协议集合起来总称为 TCP/IP。
TCP/IP 协议族里重要的一点就是分层。TCP/IP 协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层。
(由于未在书中得到关于应用层更好的解释,为了方便理解,参考阮一峰博客)
- 应用层:应用层会收到“传输层”的数据进行解读,规定应用程序的数据格式(HTTP也处于这一层)
- 传输层:对上层应用层,提供处于网络链接中的两台计算机之间的数据传输。
- 网络层:处理网络上流动的数据包。(数据包是网络传输的最小数据单位)该层规定了通过怎样的路径(传输路线)到达对方的计算机,并把数据包传送给对方。(如果需要通过多台计算机或网络设备传输,网络层的作用就是在众多选项里选择一条传输路线)
- 链路层
用来处理连接网络的硬件部分。(硬件上的范畴均在链路层的作用范围内)
利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则从链路层往上走。
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
与 HTTP 关系密切的协议 : IP 和 TCP
- IP 网际协议位于网络层,作用是把各种数据包传送给对方。为了确保数据能够准确传送,则需要满足一些条件,IP 地址和 Mac 地址。
IP 地址是指节点被分配到的地址(可更换),Mac 地址指网卡所属的固定地址(不会更改)。 - TCP 协议位于传输层,将数据节流(将大块数据分割管理),能够将数据准确可靠的传达。
TCP 的三次握手(TCP 协议能够确认数据是否送达)
发送端首先发送一个带 SYN 标志的数据包给对方。接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。最后,发送端再回传一个带 ACK 标志的数据包,代表“握手”结束。
负责域名解析的 DNS 服务
DNS(Domain Name System)服务是和 HTTP 协议一样位于应用层的协议。它提供域名到 IP 地址之间的解析服务。
- 用户:通常使用域名访问对方计算机,而不是通过 IP 地址。(语义化)
- 计算机:更擅长处理数字(IP地址),而不是域名。
为了解决这一问题,DNS 服务诞生了。DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。
各种协议与 HTTP 协议的关系
URI 和 URL
URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联网上所处的位置)。可见 URL 是 URI 的子集。
通过 URL 你可以确定一个唯一的网址。
第二章 简单的 HTTP 协议
HTTP 协议用于客户端和服务器之间的通信
请求访问文本或图像等资源的一端称为客户端,而提供资源响应的一端称为服务器。
通过请求和响应的交换达成通信
下面是从客户端发给某个 HTTP 服务器端的请求报文1
2GET /index.html HTTP/1.1
Host: hackr.jp
GET
: 表示请求访问服务器的类型(方法)/index
: 请求访问的资源对象,也叫做请求 URLHTTP/1.1
: HTTP的版本号
以上报文可以理解为:请求访问某台 HTTP 服务器上的 /index.html
页面资源。
请求报文由请求方法、请求 URL、协议版本、可选的请求首部字段和内容实体构成。
接收到请求的服务器,会将请求内容的处理结果以响应的形式返回。1
2
3
4
5
6
7
8HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
……
</html>
HTTP/1.1
: 服务器对应的 HTTP 版本200 OK
: 请求处理结果的状态码和原因短语<html>......</html>
: 资源实体的主体
HTTP 是不保存状态的协议
HTTP:无状态协议。(HTTP 协议自身不对请求和响应之间的通信状态进行保存)
HTTP/1.1 虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了 Cookie 技术。(管理通信状态)
请求 URI 定位资源
如果不是访问特定资源而是对服务器本身发去请求,可以用一个*
来代替请求 URL。1
2OPTIONS * HTTP/1.1
//查询 HTTP 服务器端支持的 HTTP 方法种类
告知服务器意图的 HTTP 方法
HTTP/1.1 中可使用的方法
GET
: 获取资源POST
: 传输实体主体(和GET
比,主要目的并不是获取响应的主体内容)PUT
: 传输文件(在请求报文的主体中包含文件内容,然后保存到请求 URI 指定位置,存在安全性问题)HEAD
: 和GET
方法类似,但不返回报文主体部分。用于确认 URI 的有效性及资源更新时间等。DELETE
: 删除文件(按请求 URI 删除指定资源,存在安全性问题)OPTIONS
: 询问支持的方法TRACE
: 追踪路径(让 Web 服务器端将之前的请求通信返回给客户端的方法)CONNECT
: 要求用隧道协议连接代理(要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信)
使用方法下达命令
向请求 URI 指定的资源发送请求报文时,采用称为方法的命令。
方法的作用在于,可以指定请求的资源按期望产生某种行为。(方法中有 GET、POST 和 HEAD 等)
持久连接节省通信量
发送请求一份包含多张图片的HTML文档对应的Web页面,会产生大量的通信开销(多次请求,不断的建立连接、断开连接)
为解决上述 TCP 连接的问题,衍生了持久连接的方法。
- 持久连接:只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。(建立一次连接,多次请求和响应)
在 HTTP/1.1 中,所有的连接默认都是持久连接 - 管线化:不用等待响应亦可直接发送下一个请求(同时并行发送多个请求,而不需要一个接一个地等待响应)。
管线化技术则比持久连接还要快。
使用 Cookie 的状态管理
之前提到了,HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。
Cookie: 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。
1
2
3
4
5
6HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed,
10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8当客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
1
2
3GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
第三章 HTTP 报文内的 HTTP 信息
HTTP 报文
用于 HTTP 协议交互的信息被称为 HTTP 报文。
请求报文及响应报文的结构
1
2
3
4
5
6
7
8
9
10//请求的格式
1 动词 路径 协议/版本
2 Key1: value1
2 Key2: value2
2 Key3: value3
2 Content-Type: application/x-www-form-urlencoded
2 Host: www.baidu.com
2 User-Agent: curl/7.54.0
3
4 要上传的数据
- 请求最多包含四部分,最少包含三部分。(也就是说第四部分可以为空)
- 第三部分永远都是一个回车(\n)
- 动词有 GET POST PUT PATCH DELETE HEAD OPTIONS 等
- 这里的路径包括「查询参数」,但不包括「锚点」
- 如果你没有写路径,那么路径默认为 /
- 第 2 部分中的 Content-Type 标注了第 4 部分的格式
编码提升传输速率
HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率(优:有效地处理大量的访问请求。缺:消耗更多的 CPU 等资源)。
- 内容编码:应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。
常用的内容编码:- gzip(GNU zip)
- compress(UNIX 系统的标准压缩)
- deflate(zlib)
- identity(不进行编码)
- 分块传输编码:在 HTTP 通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据(实体主题)分割成多块,能够让浏览器逐步显示页面。
发送多种数据的多部分对象集合
获取部分内容的范围请求
内容协商返回最合适的内容
我们会遇到一些支持多语言的网站,浏览器会根据默认语言显示相对应的网页,这样的机制称为内容协商。
内容协商机制:是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。
内容协商技术有以下 3 种类型
- 服务器驱动协商:服务器端参考请求首部字段自动处理。
- 客户端驱动协商:用户手动选择。
- 透明协商:服务器端和客户端各自进行内容协商。
第四章 返回结果的 HTTP 状态码
状态码告知从服务器端返回的请求结果
状态码如 200 OK,以 3 位数字和原因短语组成。
2XX 成功
2XX 的响应结果表明请求被正常处理了。
- 200 OK:表示从客户端发来的请求在服务器端被正常处理了。
- 204 No Content:请求处理成功,但无资源返回。(浏览器发出请求,页面不发生更新)
- 206 Partial Content:发出了获取部分资源的请求,服务器成功处理该请求,返回指定范围的实体内容(Content-Range)。
3XX 重定向
3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。
- 301 Moved Permanently:永久性重定向。请求的资源已被分配了新的 URL 。(比如已经把对应资源 URL 保存为书签,这时应该按 Location 首部字段提示的 URL 重新保存,资源被永久性移动。)
- 302 Found:暂时性重定向。请求的资源已经被分配了新的 URL 希望用户(本次)能使用新的 URL 访问。(资源不是被永久性移动)
- 303 See Other:由于请求的资源存在另一个 URL ,应使用 GET 方法定向获取请求的资源。
- 304 Not Modified:客户端发送附带条件的请求时,服务器允许请求访问资源,但因发生的请求未满足条件的情况,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)
- 307 Temporary Redirect
临时重定向。与302有着相同的含义。
4XX 客户端错误
4XX 的响应结果表明客户端是发生错误的所在。
- 400 Bad Request:请求报文存在语法错误。(需要修改请求的内容后再发送)
- 401 Unauthorized:发送的请求需要有通过
HTTP 认证的认证信息。(浏览器初次接收到401响应会弹出认证窗口,第二次则表示认证失败。) - 403 Forbidden:对请求资源的访问被服务器拒绝了。(未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源 IP 地址试图访问)等列举的情况都可能是发生 403 的原因。)
- 404 Not Found:服务器上无法找到请求的资源。(服务端拒接请求且不想说明原因时也可能返回404)
5XX 服务器错误
- 500 Internal Sever Error:服务器在执行请求时发生了错误。
- 503 Service Unavailable:服务器暂时处于超负载或正在进行停机维护,无法处理请求。
返回的状态码也有可能出错。
第五章 与 HTTP 协作的 Web 服务器
用单台虚拟主机实现多个域名
即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器。
通常客户端访问服务器,会采用域名访问,域名通过 DNS 服务映射到 IP 地址(域名解析)后访问目标网站。所以,当请求发送到服务器时,已经是以 IP 地址形式访问了。
如果一台服务器托管了两个域名,当收到请求时就需要弄清楚要访问哪个域名。
所以,相同 IP 地址下,通过虚拟主机可以寄存多个不同的主机名和域名的网站,因此在发送 HTTP 请求时,必须在 Host 首部内完整指定主机名或域名 URI。
通信数据转发程序:代理、网关、隧道
HTTP 通信时,不光是客户端和服务器之间的协作,还有一些配合服务器工作的应用程序,例如代理、网关和隧道。
- 代理:具有转发功能,接收客户端的请求转发给服务器,同时接收服务器的响应转发给客户端。
代理服务器可以利用缓存技术减少网络带宽的流量(保存资源副本,当再次接到相同资源请求,直接将缓存资源返回),添加对特定网站的访问控制等。 - 网关:接收从客户端发送来的请求时,就像自己拥有资源的源服务器一样对请求进行处理。
在客户端和网关间的通信路线上加密能提高通信的安全性(网关可以连接数据库)。 - 隧道:在客户端和服务器两者之间进行中转,保持双方通信连接。
隧道的目的是确保客户端能与服务器进行安全的通信(使用 SSL 等加密手段)。
保存资源的缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处理相同的请求了。
缓存的有效期限
如果源服务器上的资源更新,还使用不变的缓存就相当于直接返回“旧”资源了。
所以缓存代理会向源服务器确认资源的有效性,若判断缓存失效,缓存代理会重新获取“新”资源。
客户端的缓存
浏览器缓存(临时网络文件)如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。
同样的,当判断缓存失效会重新请求新资源。
第六章 HTTP 首部
HTTP 报文首部
HTTP 协议的请求和响应报文中都会包含 HTTP 首部,首部内容分别为客户端处理响应和服务器处理请求提供所需信息。
- HTTP 请求报文
在请求中,HTTP 报文由方法、URI、HTTP 版本、HTTP首部字段等部分构成。 - HTTP 响应报文
在响应中,HTTP 报文由 HTTP 版本、状态码、HTTP 首部三部分构成。HTTP 首部字段
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用语言、认证信息等内容。
HTTP 首部字段是由首部字段名和字段值构成的。1
2
3首部字段名: 字段值
Content-Type: text/html
Keep-Alive: timeout=15, max=100
HTTP 首部字段根据实际用途分为以下四种类型。
- 通用首部字段
- 请求首部字段
- 响应首部字段
- 实体首部字段
HTTP/1.1 规范定义了 47 种首部字段。
另,还有 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 中定义的首部字段。
HTTP/1.1 通用首部字段
通用首部字段指的是请求报文和响应报文双方都会使用的首部。
Cache-Control
此字段能够控制缓存行为。1
Cache-Control: private, max-age=0, no-cache
- privarte, public 指令
1
2Cache-Control: private
Cache-Control: public
当指定 private 指令后,缓存只提供给特定用户,这与 public 指令(向所有用户返回缓存)的行为相反。
- no-chche 指令
1
Cache-Control: no-cache
使用 no-cache 指令是为了防止从缓存中返回过期的资源。
- no-store 指令
1
Cache-Control: no-store
使用 no-store 指令,暗示请求或响应中包含机密信息(禁用缓存)。
- max-age 指令
1
Cache-Control: max-age=604800(单位:秒)
当资源的缓存时间比指定值小则客户端接收缓存资源(max-age 数值代表资源保存为缓存的最长时间)。
- min-fresh 指令
1
Cache-Control: min-fresh=60(单位:秒)
该指令要求缓存服务器返回至少还未过指定时间的缓存资源。
更多指令参考
Connection
该字段有以下两个作用:
Pragma
1 | Pragma: no-cache |
该字段只用在客户端发送的请求中,客户端会要求所有中间服务器不返回缓存的资源。
Trailer
该字段会事先说明在报文主体后记录了哪些首部字段(可应用在 HTTP/1.1 版本分块传输编码时)。
Transfer-Encoding
该字段规定了传输报文主体时采用的编码方式。
HTTP/1.1 的传输编码方式仅对分块传输编码有效。
Upgrade
该字段用于检测 HTTP 协议及其他协议是否可使用更高版本进行通信。
Via
该字段能够追踪客户端与服务器之间请求和响应报文的传输路径(代理服务器在 Via 首部附加服务器信息,避免请求回环的发生)。
Warning
该字段通常会告知用户一些与缓存相关的问题的警告。1
2Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
Warning: 113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03 Jul 2012 05:09:44 GMT
HTTP/1.1 中定义了 7 种警告。
请求首部字段
请求首部字段是从客户端往服务器发送请求报文中所使用的字段。
Accept
1 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
该指令可通知服务器,用户代理能够处理的媒体类型(type/subtype )及其相对优先级。
文本文件
1
text/html, text/plain, text/css ...
图片文件
1
image/jpeg, image/gif, image/png ...
视频文件
1
video/mpeg, video/quicktime ...
应用程序使用的二进制文件
1
application/octet-stream, application/zip ...
当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。
Accept-Charset
1 | Accept-Charset: iso-8859-5, unicode-1-1;q=0.8 |
通知服务器用户代理支持的字符集及其相对优先级(可用权重 q 值来表示相对优先级)。
Accept-Encoding
1 | Accept-Encoding: gzip, deflate |
该字段用于告知服务器用户代理支持的内容编码及其优先级(采用权重 q 值来表示相对优先级)。
该字段用来告知服务器用户代理能够处理的自然语言集及其优先级(按权重值 q 来表示相对优先级)。
Host
1 | Host: www.hackr.jp |
该字段告知服务器,请求的资源所处的互联网主机名和端口号。
Range
1 | Range: bytes=5001-10000 |
对于只需获取部分资源的范围请求,该字段告知服务器资源的指定范围。
接收到附带 Range 首部字段请求的服务器,会返回206 Partial Content 的响应。或在无法处理该请求时返回状态码 200 OK 的响应及全部资源。
Referer
1 | Referer: http://www.hackr.jp/index.htm |
该字段会告知服务器请求的 URI 是从哪个 Web 页面发起的
因为原始资源的 URI 中的查询字符串可能含有 ID 和密码等保密信息,要是写进 Referer 转发给其他服务器,则有可能导致保密信息的泄露。
User-Agent
首部字段 User-Agent 会将创建请求的浏览器和用户代理名称等信息传达给服务器。
更多字段参考
响应首部字段
Accept-Ranges
1 | Accept-Ranges: bytes |
该字段用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分资源。
可指定的字段值有两个,可处理范围请求时指定其为bytes
,反之则指定为none
。
Age
该字段能告知客户端,源服务器在多久之前创建了响应。(单位:秒)1
Age: 600
代理创建响应时必须加上首部字段 Age。
ETag
当资源被缓存时,服务器会为客户端实体分配的唯一标识。
当资源更新时,ETag值也会被重新分配。
Location
使用该字段可将响应接收方引导至与请求 URI 位置不同的资源。
Proxy-Authenticate
该字段将代理服务器要求的认证信息发送给客户端。
Retry-After
1 | Retry-After: 120 |
该字段告知客户端应该在多久之后再次发送请求。
Server
1 | Server: Apache/2.2.17 (Unix) |
该字段告知客户端当前服务器安装的 HTTP 服务器应用程序的信息。
Vary
1 | Vary: Accept-Language |
从代理服务器接收到源服务器返回包含 Vary 指定项的响应之后,若要再进行缓存,仅对请求中含有 Vary 指定首部字段的请求返回缓存。
WWW-Authenticate
该字段用于 HTTP 访问认证。
实体首部字段
Allow
1 | Allow: GET, HEAD |
该字段用于通知客户端支持的 HTTP 方法。
Content-Encoding
1 | Content-Encoding: gzip |
告知客户端对实体主体部分选用的内容编码方式。
内容编码:是指在不丢失实体信息的前提下所进行的压缩。
Content-Language
告知客户端实体主题使用的自然语言。
Content-Length
该字段表明实体主体部分大小(单位:字节)。
Content-Location
该字段表示报文主体返回资源对应的 URI。
Content-MD5
Content-Range
1 | Content-Range: bytes 5001-10000/10000 |
告知客户端作为响应返回的实体的哪个部分符合范围请求。(单位:字节)
Content-Type
1 | Content-Type: text/html; charset=UTF-8 |
该字段说明了实体主体内对象的媒体类型。
Expires
1 | Expires: Wed, 04 Jul 2012 08:26:05 GMT |
该字段会将资源失效的日期告知客户端。
Last-Modified
1 | Last-Modified: Wed, 23 May 2012 09:59:55 GMT |
该字段指明资源最终修改的时间。
为 Cookie 服务的首部字段
Cookie 的工作机制是用户识别及状态管理。
Web 网站为了管理用户的状态,通过浏览器将一些数据临时写入计算机。当用户访问该网站时,会取回之前存放的 Cookie。
当再次调用 Cookie 时,由于可校验 Cookie 的有效期,以及发送方的域、路径、协议等信息,所以 Cookie 内的数据不会被攻击和泄漏。
Set-Cookie
1 | Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; path=/; domain=.hackr.jp; |
当服务器对客户端进行管理时,会事先告知各种信息。也就是 Set-Cookie。
- expires 属性
该属性指定浏览器可发送 Cookie 的有效期。(若未明确指定,则默认为浏览器关闭前为止) - path 属性
该属性限制指定 Cookie 的发送范围(文件目录)。 - domain 属性
该属性指定的域名都可发送 Cookie。比如
baidu.com,www.baidu.com 都可以发送 Cookie。(不指定 domain 属性更安全) - secure 属性
该属性用于限制 Web 页面仅在 HTTPS 安全连接时才可以发送 Cookie。1
Set-Cookie: name=value; secure
也就是说,即使域名相同也不会进行 Cookie
回收。
- HttpOnly 属性
该属性使 JavaScript 脚本无法获得 Cookie。1
Set-Cookie: name=value; HttpOnly
目的:防止跨站脚本攻击对 Cookie 的信息窃取
Cookie
1 | Cookie: status=enable |
Cookie 会告知服务器,当客户想获得 HTTP 状态管理支持时,就会在请求中包含从服务器收到的 Cookie。
其他首部字段
第七章 确保Web 安全的 HTTPS
HTTP 的缺点
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已经被篡改
通信使用明文可能会被窃听
HTTP不具备加密功能(明文传输),无法对请求和响应的过程加密。
互联网是由能连接世界的网络组成的,通信心路上的设备不可能是个人私有物,所以不排除在某个环节被窥视。
但是加密后的报文还是有可能会被看到的。
- 窃听:收集在互联网上流动的数据包,再交给抓包工具解析。
- 加密:可通过SSL(Secure Socket Layer,安全套接层)或 TLS(Transport Layer Security,安全传输层协议)的组合使用,加密 HTTP 的通信内容。或者(客户端)对 HTTP 报文所含内容进行加密处理再请求。
不验证通信方的身份就可能遭遇伪装
服务器是否就是发送请求中 URI 真正指定的主机,返回的响应是否真的返回到实际提出请求的客户端?
证书:
通过使用证书,以证明通信方就是意料中的服务器。这对使用者个人来讲,也减少了个人信息泄露的危险性。无法证明报文完整性,可能已遭篡改
没有任何办法确认,发出的请求 / 响应和接收到的请求 / 响应是前后相同的。
比如,从网站上下载的文件无法确认与服务器上存放的文件一致。
为了有效防止这些弊端,有必要使用 HTTPS。
HTTP+加密+认证+完整性保护=HTTPS
我们把添加了加密及认证机制的 HTTP 称为 HTTPS(HTTP Secure)。
HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。
SSL 是当今世界上应用最为广泛的网络安全技术。
SSL 采用一种叫做公开密钥加密(Public-key cryptography)的加密处理方式。
HTTPS 采用混合加密机制
在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
证明公开密钥正确性的证书
遗留问题,无法证明公开密钥本身就是货真价实的公开密钥。
可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书。
客户端证书:银行的网上银行就采用了客户端证书。在登录网银时不仅要求用户确认输入 ID 和密码,还会要求用户的客户端证书,以确认用户是否从特定的终端访问网银。
要进行 HTTPS 通信,证书是必不可少的。而使用的证书必须向认证机构(CA)购买。
第八章 确认访问用户身份的认证
何为认证
计算机本身无法判断在显示器前的使用者的身份。为了弄清楚谁在访问服务器,就得让对方的客户端自报家门。
需要核对“登陆者本人才知道的信息”、“登陆者本人才会有的信息”。
- 密码:只有本人才会知道的字符串信息
- 动态令牌:仅限本人持有的设备内显示的一次性密码
- 数字证书:仅限本人(终端)持有的信息
- 生物认证:指纹和虹膜等本人的生理信息
- IC 卡等:仅限本人持有的信息
HTTP 使用的认证方式
- BASIC 认证(基本认证)
- DIGEST 认证(摘要认证)
- SSL 客户端认证
- FormBase 认证(基于表单认证)
Windows 统一认证(Keberos 认证、NTLM 认证),此处不做详解。
BASIC 认证
BASIC 认证使用上不够便捷灵活,且达不到多数 Web 网站期望的安全性等级(比如直接发送明文密码),因此它并不常用。
DIGEST 认证
使用质询/响应的方式
因为发送给对方的只是响应摘要及由质询码产生的计算结果,所以比起 BASIC 认证,密码泄露的可能性就降低了。
DIGEST 认证提供了高于 BASIC 认证的安全等级,但是和 HTTPS 的客户端认证相比仍旧很弱。
SSL 客户端认证
使用 SSL 客户端认证可避免用户账号密码被盗。
SSL 客户端认证是借由 HTTPS 的客户端证书完成认证的方式。
SSL 客户端认证步骤
- 颁发客户端证书,客户端安装证书
- 接收到资源请求,服务器会发送 Certificate Request 报文,要求客户端提供客户端证书。
- 用户选择发送的客户端证书后,客户端会把客户端证书以 Certificate Request 报文方式发送给服务器。
- 服务器验证客户端证书,通过后可领取证书内客户端公开密钥,然后开始 HTTPS 加密通信。
SSL 客户端认证采用双因素认证
对数情况下,不光是通过证书认证,还要基于表单认证组合形成一种双因素认证。
换言之,第一个认证因素是认证客户端计算机(证书),第二个通过密码来确认用户本人的行为。
SSL 客户端认证必要的费用
使用 SSL 客户端认证需要用到客户端证书。而客户端证书需要支付一定费用才能使用(购买费用)。
基于表单验证
客户端向服务器发送登陆信息验证。
多数情况,输入已事先登陆的用户 ID(任意字符或邮件地址)和密码等信息后,发送给 Web 应用程序,基于认证结果来决定认证是否成功。
认证多半基于表单认证
BASIC,DIGEST认证便利和安全性问题。
SSL 维持费用高昂。
所以,如果是全面考虑过安全性能而实现的表单验证,那么就能够具备高度的安全等级且足够的便利。
Session 管理及 Cookie 应用
表单验证本事是通过 Web 应用,将客户端发送过来的用户 ID 和密码与之前登陆过的信息匹配来进行认证的。
但是 HTTP 本是无状态协议,认证过的用户状态无法通过协议层面保存。于是会使用 Cookie 来管理 Session(会话)。
- 客户端将用户账号密码以 POST 方式发送给服务器。
- 服务器发放识别用户的 Session ID 。通过验证从客户端发送过来的登陆信息进行身份验证,然后把用户认证状态与Session ID 绑定后记录在客户端。
向客户端返回响应时,会在首部 Set-Cookie 内写入 Session ID
- 客户端接收到从服务器端发来的 Session ID 后,将其作为Cookie 保存在本地。下次发送请求时,浏览器会自动发送 Cookie,所以 Session ID 也随之发送到服务器。
服务器通过验证接收到的 Session ID 识别用户认证状态。
第九章 基于 HTTP 的功能追加协议
基于 HTTP 的协议
HTTP 功能上的不足可通过创建一套新的协议弥补。可是目前基于HTTP 的 Web 浏览器的使用环境遍布全球,因此无法彻底抛弃 HTTP。有一些新协议的规则是基于 HTTP 的,并在此基础上添加新功能。
消除 HTTP 瓶颈的 SPDY
Google 在 2010 年发布来 SPDY,缩短
Web 页面的加载时间(50%)。
HTTP 瓶颈
- 一条连接上只可发送一个请求
- 请求只能从客户端开始。客户端不可以接收响应意外的的指令
- 请求/响应 首部未经压缩就发送。首部信息越多延迟越大
- 发送冗长的首部,每次互相发送相同的首部造成的浪费较多
- 可任意选择数据压缩格式,非强制压缩发送
当在 Facebook 和 Twitter 等 SNS 网站上即时更新海量的内容会产生大量的徒劳通信及行性能问题。
Ajax 的解决方法
从家在完毕的 Web 页面上发送请求,只更新局部页面。
Comet 的解决方法
一旦服务器端有内容更新了,Comet 不会让请求等待,而是直接给客户端返回响应。(通过延迟应答,模拟服务器向客户端推送)
内容上虽然可以做到实时更新,但是为了保留响应,一次连接的时间也变长了,维持连接也会消耗资源。
SPDY 的目标
Ajax 和 Comet 等提高易用性的技术,一定程度上使 HTTP 得到了改善,但是仍未解决 HTTP 协议本身存在的问题。
处于持续开发状态中的 SPDY 协议,正是为了在协议级别消除 HTTP 所遭遇的瓶颈。
SPDY 的设计与功能
SPDY 没有完全改写 HTTP 协议,而是在 TCP/IP 的应用层与传输层之间通过新加会话层的形式运作(使用SSL)。
- 多路复用流
在一条TCP 连接上无限制处理多个 HTTP 请求,提高 TCP 处理效率 - 赋予请求优先级
给请求逐个分配优先级顺序,解决因带宽低导致响应变慢的问题。 - 压缩HTTP 首部
减少通信产生的数据包数量和发送的字节数 - 推送功能
支持服务器主动向客户端推送数据的功能,不必等待客户端请求。 - 服务器提示功能
服务器主动提示客户端请求所需资源,避免发送不必要的请求。
SPDY 消除 Web 瓶颈了吗
PDY 基本上只是将单个域名( IP 地址)的通信多路复用,所以当一个 Web 网站上使用多个域名下的资源,改善效果就会受到限制。
使用浏览器进行全双工通信的 WebSocket
WebSocket 在 2011 年 12 月 11 日被 RFC 6455 - The WebSocket Protocol 定为标准。
WebSocket 的设计与功能
为了解决 Ajax 和 Comet 里 XMLHttpRequest 附带的缺陷所引起的问题。
WebSocket 协议
当客户端与服务器之间建立 WebSocket 协议通信连接,之后的通信都会依靠此协议进行。通信过程中可互相发送 JSON、XML、HTML 或图片等任意格式数据。
该协议建立在 HTTP 基础上,一旦确立 WebSocket 通信连接,不论客户端还是服务器,任意一方都可直接向对方发送报文。
- 推送功能
支持由服务器向客户端推送数据的推送功能,不必等待客户端的请求。 - 减少通信量
一直保持连接状态,首部信息很小,通信量也相应减少了。 - 握手·请求
- 握手·响应
- WebSocket API
JavaScript 可调用“The WebSocket API”,内提供的 WebSocket 程序接口,以实现 WebSocket 协议下全双工通信。1
2
3
4
5
6
7var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function () {
setInterval(function() {
if (socket.bufferedAmount == 0)
socket.send(getUpdateData());
}, 50);
};
上面的代码为调用 WebSocket API,每 50ms 发送一次数据的实例。
期盼已久的 HTTP/2.0
特点:
- SPDY
- HTTP Speed + Monility
HTTP Speed + Mobility 由微软公司起草,是用于改善并提高移动端通信时的通信速度和性能的标准。 - Network-Friendly HTTP Upgrade
Network-Friendly HTTP Upgrade 主要是在移动端通信时改善 HTTP 性能的标准。
Web 服务器管理文件的 WebDAV
是一个可对 Web 服务器上的内容直接进行文件复制、编辑等操作的分布式文件系统。
除了创建、删除文件等基本功能,它还具备文件创建者管理、文件编辑过程中禁止其他用户内容覆盖的加锁功能,以及对文件内容修改的版本控制功能。
扩展 HTTP/1.1 的 WebDAV
WebDAV 内新增的方法及状态码
在 HTTP/1.1 中追加
详细内容参照