[ 输入url到获取页面的网络过程 ]
将其流程列出大致如下:
- 构建请求,查找缓存
- 确定ip地址
- 建立TCP连接
- HTTP请求响应
- 客户端发起HTTP请求
- 服务器响应HTTP请求
- 断开TCP连接
1.[ 构建请求,查找缓存 ]
-
[ 构建请求 ] 根据url提供的协议、域名、端口等信息构建一个HTTP请求。
-
[ 查找缓存 ] 在请求构建后,浏览器会根据请求头的expires或cache-control字段,判断所需资源的强缓存策略是否命中,如果命中强缓存则不会发送该资源的请求。 如果强缓存策略没有命中,则浏览器会发送请求,根据请求头的If-Modified-Since和If-None-Match字段,判断资源是否命中协商缓存,没有命中则从服务器中获取资源。
-
[ HSTS启用 ] 请求发起后,如果服务器的响应头含有Strict-Transport-Security字段,则意味着服务器启用HSTS,会强制要求客户端使用HTTPS访问页面,发起请求。
2.[ 确定ip地址 ]
-
[ 查询DNS,确定ip地址 ] 发起请求之前,需要知道url对应的IP地址及其端口号,这需要通过DNS服务器去找到url对应的IP地址。 那么需要找到url对应的ip地址,则需要找到DNS服务器的ip地址,一般每台电脑的操作系统在安装时,就已经在本机的网络设置中,设置了DNS服务器的IP地址,否则是无法联网的。
-
[ IP协议,ip地址 ] IP协议指的是IPv4,IPv6等协议,而ip地址是建立在IP协议之上的,两者需要作出区分。
2*.[ DNS域名解析原理 ]
-
[ 角色 ] DNS对域名进行解析过程共有三个角色,客户端/浏览器,DNS域名解析器/DNS客户端、DNS服务器。 浏览器不会直接于DNS服务器进行通信,而是将url中的域名及相关信息传递给DNS域名解析器,让DNS域名解析器去与DNS服务器进行通信,因此DNS域名解析器相当于DNS服务器的客户端,又称DNS客户端。 而DNS服务器记录了所有域名对应的ip,从而能够根据得到的域名,返回对应的ip。
-
[ IPv4与IPv6 ] IPv4与IPv6为两个前后版本的IP协议。 IPv4协议下的ip地址采用32位数进行表示,因此其最大ip地址数量为2的32次方,在除去特殊地址用于特殊用途,或作为基本ip地址外,能够提供使用的ip地址数量,伴随互联网的发展已经不够使用。 IPv6协议下的ip地址采用128位数进行表示,因此其最大的ip地址数量为2的128次方,是足够使用的。
-
[ 域名结构树 ] 域名是具有等级的,以www.example.com为例。 三级域名:该域名层级的域名有www、mail、member、space,通过该层级的域名可以得知该域名对应的是站点,还是邮件或其他。该层级的域名是最低层级。 权限域名:该域名层级表示该域名归属example管理,其下级域名可以有www、mail、member、space。例如:.baidu.com下有mail.baidu.com、www.baidu.com等等,同时.bilibili.com下也有www.bilibili.com、mail.bilibili.com等等。 顶级域名:该域名层级表示该域名的更上级归属管理,该层级的域名有:.com、.cn、.net等等。因此.baidu、.bilibili都是归属与.com管理的域名。 根域名:www.example.com后其实省略了.,.表示根域名,最高级域名。因此.com、.cn、.net都归属.管理。 从根域名向三级域名,形成了一颗域名结构树。
-
[ 域名解析过程 ]
-
[ 记录查询 ] 当DNS域名解析器获得域名后,不会第一时间与DNS服务器通信,而是先在浏览器的记录中查找,是否先前有先前的记录能够找到该域名对应的ip地址,有则直接使用,无则与DNS服务器通信。
-
[ DNS解析器中介 ] 浏览器会将域名传递给DNS解析器,让其与DNS服务器通信,查找域名的对应ip地址。而DNS服务器的ip地址存储于客户端设备中,客户端设备如果没有存储DNS服务器的ip地址将无法正常上网,在设备初始化中会有存储。
-
[ ISP ] DNS服务器一般由ISP进行管理,电信,移动,联通都属于ISP。
-
[ 缓存查询 ] DNS服务器会查找自身的缓存结果中,是否有与请求提供的域名一直的结果,如果缓存结果中存在,则直接将缓存的结果返回给DNS解析器,直接调用缓存得到的ip地址会被non-authoritative字段标记为非权威结果。
-
[ 迭代查询 ] 以www.example.com为例,DNS服务器会向根域名服务器查询,得到顶级域名服务器的地址,即.com服务器地址。 然后会向.com服务器查询,得到权限域名服务器地址,即.bilibili.com的服务器地址。 再向权限服务器查询,得到www.bilibili.com的地址,从而找到目标ip地址。 这个过程是迭代的,即上一次的结果作为下一次的参数,形成环结构,且这个过程DNS服务器一共得到3次返回结果,进行了3次迭代得到最后的结果。
-
[ 递归传递 ] 以www.example.com为例,DNS解析器让DNS服务器查询根域名服务器,再让DNS服务器查询顶级域名服务器,再让DNS服务器查询权限域名服务器,得到ip地址。 这个过程是递归的,即对同一个参数连续进行3次执行,得到ip地址,这个过程只得到一个返回结果。
-
[ ip地址逐级返回 ] DNS服务器得到ip地址会返回给DNS解析器,DNS解析器再返回给浏览器,浏览器便可以向目标ip地址准备请求的发送。
-
3.[ 建立TCP连接 ]
- [ TCP通道 ] HTTP/HTTPS请求是建立在TCP的连接通道之上,上述的查找缓存中的协商缓存是需要发起请求后才会确认是否命中的,因此协商缓存过程在TCP连接建立后才会进行。
- [ HTTP无状态无连接 ] HTTP是一个无状态无连接的协议。
其无状态指的是其本身只有请求和响应两种行为,即要么就是发起请求,要么就是等待响应,并且多个请求直接不会相互干扰,不会因为上一个请求的响应失败而导致协议状态的改变,从而影响下一个请求的响应。
HTTP借助与TCP通道进行传输,因此有连接的是TCP协议,HTTP本身是无连接的。
-
[ 三次握手 ] 三次握手是协助HTTP请求的TCP连接行为。而这种连接行为用TCP标示表示。TCP标示有很多,包括:SYN,ACK,PSH,FIN,RST,URG。 三次握手表示HTTP请求发起前的TCP通道建立。
-
[ 同步 ] TCP的连接和断开是通过同步方式进行的,同步需要双方都发起一次请求,并且另一方都确认。不以同步方式进行的连接,就像男方向女方告白,女方同意了就可以交往;而以同步方式进行的连接,不仅需要男方向女方告白后女方同意,还需要女方再向男方告白且男方同意,才能交往。 因此TCP的连接和断开,需要双方都发起一次请求,并且双方都要确定对方的请求,这就是TCP连接可靠的依据。
-
[ SYN标示 ] 客户端或服务器的其中一方向另一方发起的一次连接同步请求,称为SYN。SYN表示一方向另一方发起连接同步请求。 SYN会伴随一个seq随机数,另一方确认同步后需要返回该随机数+1。
-
[ FIN标示 ] 客户端或服务器的其中一方向另一方发起的一次断开同步请求,称为FIN。FIN表示一方向另一方发起断开同步请求
-
[ ACK标示 ] 客户端或服务器的其中一方确认另一方的一次同步请求,称为ACK。ACK表示一方确认另一方发起的请求。 ACK会伴随一个ack随机数,为同步发起方SYN伴随的seq随机数+1。
-
-
[ 握手过程 ]
-
[ 第一次握手 ] 第一次握手表示客户端告知服务器,客户端已经完成HTTP请求的构建,可以建立TCP通道。 SYN=1,seq=x;
-
[ 第二次握手 ] 第二次握手表示服务器确认客户端建立TCP通道的请示,并告知客户端完成TPC通道的建立准备。 ACK=1,ack=x+1,SYN=1,seq=y;
-
[ 第三次握手 ] 第三次握手表示客户端已经确认服务器完成TPC通道的建立准备,进行TPC通道的建立连接。 ACK=1,ack=y+1;
-
-
[ 四次挥手 ]
-
[ 第一次挥手 ] 第一次发起断开同步请求的可以是客户端或服务器任意一方,这里以客户端主动发起为例。 客户端向服务器发起断开同步请求。 FIN=1,seq=x;
-
[ 第二次挥手 ] 服务器确认客户端的断开同步请求。 ACK=1,ack=x+1;
-
[ 中间过程 ] 在服务器确认断开同步请求之后,不会立刻发起自身的断开同步请求,在这个中间过程会进行一下数据处理,数据通信。 就像男方或女方突然被对方分手后,还需要准备分手后搬离同一个房间,分配个人物品等等事项。 挥手过程会比握手过程多一次的原因在于,第二次握手时,服务器确定客户端连接同步请求后立刻也发起了自身的连接同步请求,而挥手过程,被断开方不会立刻发起自身的断开同步请求。
-
[ 第三次挥手 ] 服务器向客户端发起断开同步请求。 FIN=1,seq=y;
-
[ 第四次挥手 ] 客户端确认断开同步请求。 ACK=1,ack=K+1;
-
4.[ HTTP协议基本概念 ]
-
[ HTTP协议 ] HTTP是一个基于请求响应模式的无连接无状态应用层协议,浏览器服务器之间的数据通信建立在其之上。
-
[ 无连接 ] HTTP协议的连接来自于传输层的TCP协议的连接,因此本身是无连接的。
-
[ 无状态 ] HTTP协议的无状态,即同一TCP连接下的多个请求是没有关联的,不会因为单个请求的失败影响其他请求的状态,但HTTP协议是有会话的,请求直接并非完全没有关联,可以通过cookie使多个请求产生关联,而使用cookie就使得HTTP创建了有状态的会话。
-
[ 无状态的缺点 ] HTTP的无状态意味着多条请求之间没有联系,在大量的数据传输的长连接场景中,传输数据的同时,需要同时传输上下文信息,确保信息传输的可靠稳定。在JWT中cookie携带登录信息就是上下文信息,每次都需要携带的cookie就消耗了更多网络开销。
-
[ 无状态的优点 ] 与长连接场景相对的简单数据信息传输场景,如果本身就没有关联的请求间,又通过协议状态去强调之间的联系,反而增加了网络开销。
-
[ 可靠性 ] HTTP协议之间的数据传输建立在TCP连接的基础上,使得HTTP协议继承了TCP连接的可靠性。
-
[ 明文传输 ] HTTP协议下的报文采用明文传输,即其数据并非是二进制,而是文本形式。明文传输使得开发调试更加便利,但也更不安全。
-
-
[ HTTP报文基本概念 ]
-
[ 构成 ] HTTP报文共由四个部分组成,分别为请求/状态行,首部行(标头)(Headers),空行,实体主体。请求与响应实际上就是报文,即请求报文与响应报文。
-
[ 请求行 ] 请求行由有序的三部分组成:请求方法(Method),资源路径(path),协议版本(Version of the protocol)。
GET / HTTP/1.1以该请求行为例,请求方法为GET,资源路径为/,协议版本为HTTP/1.1。在初学时很容易误以为资源路径被省略了,认为/是请求方法与协议版本之间的分隔符。
-
[ 状态行 ] 状态行由有序的三部分组成:协议版本(Version of the protocol),响应状态码(Status code),状态信息(Status massage)。
-
[ 首部行 ] 首部行往往由多个字段的键值对构成,其中包含请求或响应的更多信息。
-
[ 实体主体 ] 一般响应报文会携带响应主体体,响应主体往往是请求所需要的数据,而请求主体是否存在取决于请求方式,当请求方式需要客户端发送数据时,客户端的数据通过请求主体发送。
-
-
[ 请求方法基本概念 ]
-
[ 特性 ] 每个请求方法都有固定的特性,其中特性包含:响应是否有主体,是否安全,是否幂等,是否可缓存,HTML表单是否支持。
-
[ 响应是否有主体 ] 响应报文的实体主体往往携带请求报文所需要的数据,响应报文没有实体主体,意味着本次请求不需要响应报文携带过多数据。
-
[ 安全 ] 针对HTTP方法的安全,指的是其是否会修改服务器的数据,即来自客户端的请求响应后,是否会对服务器的数据造成影响。所有被定义为安全的请求方法都是幂等的。
-
[ 幂等 ] 幂等指的是同样的请求方式在不变的客户端与服务器状态中,多次请求其结果是不变的。是否幂等与服务器状态紧密相关,即便是被定义为幂等的请求方法,也会因为服务器状态的变动而不幂等。
-
[ 可缓存 ] 即该请求方法得到的响应结果是否可用被缓存,而是否缓存取决于强缓存和协商缓存两种方式。
-
[ HTML表单是否支持 ] 即form标签是否直接支持该请求方式。
-
5.[ 请求方法 ]
-
[ GET ]
-
[ 概念 ] GET方法用于请求指定的资源,GET请求只用于获取数据。响应会通过主体携带数据。
-
[ 特性 ] 响应有主体、安全、幂等、可缓存、表单支持。
-
-
[ HEAD ]
-
[ 概念 ] HEAD方法用于请求特定资源的首部行。因为其只请求首部行,因此响应不会携带主体,HEAD方法相当于一个不返回响应主体的GET方法。
-
[ 作用 ] 当一个请求指定的资源获取需要占用较高开销时,如果通过GET请求直接获取,则直接获得到了指定资源并消耗了开销。而通过HEAD方法,能得到响应标头上的资源信息,从而根据响应标头的信息去判断获取该资源的开销。
-
[ 特性 ] 响应无主体、安全、幂等、可缓存、表单不支持。
-
-
[ POST ]
-
[ 概念 ] POST方法用于将客户端数据发送给服务器,其请求主体携带需要发送的数据。POST方法对应的响应主体是接受来自客户端的数据并修改后的服务器上的数据。
-
[ 特性 ] 响应有主体、不安全、非幂等、缓存取决于发送的数据是否有新数据、表单支持
-
-
[ PUT ]
-
[ 概念 ] 当服务器上不存在目标资源,则PUT方法会将客户端发送的数据作为服务器的该目标资源。当服务器上存在目标资源,则PUT方法会将客户端发送的数据替代服务器的目标资源。 服务器目标资源新建为客户端发送的数据时,响应状态码为201(Created)。 服务器目标资源替换为客户端发送的数据时,响应状态码为200(OK)或204(No Content)。
-
[ 特性 ] 响应无主体、不安全、幂等、无缓存、表单不支持。
-
-
[ DELETE ]
- [ 概念 ] DELETE方法可以使客户端向服务器发起删除服务器上目标资源的请求。 服务器接受请求,但未执行删除,返回响应状态码202(Accepted)。 服务器接受请求,并执行删除,返回响应状态码204(No Content)。 服务器接受请求,并执行删除,回馈相关信息,返回响应状态码200(OK)。
-
[ CONNECT ]
-
[ 概念 ] CONNECT方法用于开启一个客户端与服务器之间的隧道(tunnel)。
-
[ 作用 ] CONNECT方法可以通过开启隧道的方式,访问一个HTTPS协议的服务器。客户端是通过代理服务器与目标服务器建立TCP连接的形式开启隧道,而并非客户端与服务器之间的直接隧道。
-
[ 特性 ] 响应有主体、不安全、非幂等、无缓存、表单不支持。
-
-
[ OPTIONS ]
-
[ 概念 ] OPTIONS方法用于获取目标资源所支持的通信选项。如果OPTIONS方法对应的请求行中的路径为*,即OPTIONS方法会获取目标服务器支持的所有请求方法。
-
[ 特性 ] 响应有主体、安全、幂等、无缓存、表单不支持。
-
-
[ PATCH ]
-
[ 概念 ] PATCH方法用于对目标资源的修改。其与PUT方法的区别在于,PUT方法对目标资源的更新是通过新值覆盖的方式实现的,而PATCH方法对目标资源的更新是通过旧值修改的方式实现的。无论PUT方法重复请求多少次,其都是进行多次覆盖,结果保持幂等,而PATCH方法重复请求,则会进行多次的修改。例如要将1修改为2,PUT是直接用2覆盖1,而PATCH是通过+1得到2的方式实现。 当服务器支持PATCH方法,其响应标头的Allow或Access-Control-Allow-Methods的字段会添加PATCH在其方法列表中。
-
[ 特性 ] 响应无主体、不安全、不幂等、无缓存、表单不支持。
-
-
[ TRACE ]
- [ 概念 ] TRACE方法主要是用于debug。
6.[ 响应状态码(自己查表) ]
7. [ 缓存 ]
在构建完请求后,浏览器存在一个缓存查询的环节,当客户端请求需要的数据资源,在客户端本地已经存储时,就可以调用本地资源,而不需要向服务器获取,以得到更快的资源加载速度,节省不必要的网络开销。上述提及了强缓存,弱缓存的基本概念,不再复述。
-
[ 强缓存 ] 向服务器请求资源的请求报文,其请求的资源若有强缓存,则会在标头上携带Cache-Control字段与Etag字段,在http1.1规范后使用Cache-Control与Etag字段,在http1.1规范前使用Expires字段与Etag字段。 如果请求报文的请求资源对应的强缓存命中,则不会将请求发送,直接使用强缓存提供的资源。
-
[ Etag ]
- [ 概念 ] Etag字段是缓存的标识符。
-
[ Cache-Control ]
-
[ 概念 ] Cache-Control字段用于表示当前请求的资源对应的强缓存剩余时间。如Cache-Control: max-age=3600,即表示当前请求需要资源对应的本地缓存剩余时间为3600秒。当Cache-Control字段对应的缓存剩余时间用完时,意味着当前请求对应的本地缓存是过期的。 Cache-Control字段是在http1.1规范后提出的字段。
-
[ 字段属性 ] max-age用于表示当前请求对应的资源强缓存距离过期的剩余时间。 s-maxage与max-age表示的意义一致,但max-age用在客户端,而s-maxage用于代理服务器。 private属性表明当前请求对应的资源强缓存只允许存储在客户端,不允许存储在代理服务器。 public属性表明代理服务器与客户端都可以存储强缓存。 no-store属性表明当前请求对应的资源强缓存没被存储。 no-cache属性表明当前请求对应的资源强缓存已存储但不可以。
-
-
[ Expires ]
- [ 概念 ] Expires字段表示强缓存可用的方式不同,Cache-Control是表示距离过期的剩余时间,而Expires字段表示在哪天过期。 例如Expires: Wed, 21 Oct 2015 02:30:00 GMT。 Expires存在的问题在于,客户端调整了本地时间后,会对齐造成影响,其过期日期是以客户端本地时间为标准,而并非服务器提供的时间。
-
-
[ 协商缓存 ] 当Cache-Control或Expires字段表明强缓存过期,或其他情况导致强缓存不可用,则客户端会通过协商缓存的方式,去让服务器决定延长强缓存的资源可用时间,还是返回新的资源作为缓存。 服务器决定延长缓存资源使用时间,则会返回响应状态码为304的响应,如果需要新的缓存,则会返回响应状态码为200的响应。
-
[ if-none-match ] 在协商缓存的请求标头中,该字段即是过期的强缓存Etag字段。当得到新的缓存时,Etag则是缓存的新标识符,而if-none-match字段则存储了旧标识符。
-
[ Last-modified ] 表示本地缓存的最后修改时间。
-
[ if-modified-sinse ] 当得到新的缓存时,Last-modified字段的值会变更,而if-modified-since会存储旧的Last-modified的值。
8. [ HTTPS加密原理 ]
-
[ 概念 ] HTTP协议的明文传输等原因导致其安全性有所欠缺,因此产生了通过SSL或TLS协议加密后的加密版本,HTTPS协议。
-
[ SSL ] Secure Sockets Layer,译名安全套接层,是旧的标准安全技术,已经被TLS协议取代。SSL层辅助加密是通过对称加密和非对称加密方式实现的。
-
[ TLS ] Transport Layer Security,译名传输层安全性协议,前身是SSL。TLS协议不仅支持SSL层的对称与非对称加密通信方式,还加入了数字证书。其需要在TCP连接后,进行四次握手建立TLS连接。
-
[ 加密解密 ]
-
[ 加密 ] 加密行为可以用日常中通俗的例子去理解。为一把锁配钥匙,为一个账户设置密码,为一个指纹锁设置指纹,都是属于加密行为。因此加密能够产生解密密钥,加密是产生密钥的行为。
-
[ 解密 ] 理解了加密就很容易理解解密,解密则是使用目标加密产生的密钥,解开目标的行为。解密是使用密钥的行为。
-
-
[ 对称加密通信 ]
-
[ 对称加密 ] 客户端服务器连接前,双方都会进行一次加密,并产生密钥,即客户端加密产生了一把获取客户端信息的密钥,服务器加密产生了一把获取服务器信息的密钥,共两个密钥。此后双方发送的加密信息都需要由自身的密钥解开加密。
-
[ 密钥交换 ] 此时还没有进行正式的数据通信,因为客户端和服务器双方都没有对方的密钥,无法解密对方的传递的数据信息,因此客户端服务器双方需要交换密钥。
-
[ 对称通信 ] 在交换密钥后,服务器接受到来自客户端的加密信息就能够用之前交换得到的密钥解密,客户端接受到来自服务器的加密信息也能用之前交换得到的密钥解密。
-
[ 缺陷 ] 显而易见,如果密钥交换万无一失则是安全的,但密钥交换过程是极具风险的过程,第三者能够在密钥交换过程截取密钥。
-
-
[ 非对称加密通信 ]
-
[ 信息接受方加密 ] 在对称加密通信中,密钥是由信息发送方产生的,这样不可避免的导致,接收方要接受来自发起方的信息,就需要发起方手上的密钥,产生了不安全的密钥传递。 这时产生了一种方式,由信息接受方进行加密产生密钥,即密钥由信息接收方产生,避免了密钥传递。
-
[ 公钥私钥机制 ] 此时又产生了问题,加密过程由信息接受方加密了,那么发起方要怎么给信息加密。因此产生了一个新的概念,公钥。 信息接受方先制造锁的原型,以及解锁的密钥,然后把锁给信息发送方,告诉它每次发送信息加密,都用这把锁加密,而这把锁是一把高科技锁,正常的锁可以通过锁孔等等制造出钥匙,而这把锁不能逆向制造钥匙,正常的锁必须先打开后才能加密,这把锁不用解开,就能给信息上锁。 于是信息发送方都给发送的信息用这把神奇的锁加密,而这把神奇的锁只有制造锁原型的人才有密钥,即信息接受方才能解密。 而这个高科技锁,被称为公钥,而打开这把高科技锁的密钥,被称为私钥。 公钥与私钥是缺一不可的成对组合。
-
[ 非对称加密通信过程 ] 客户端与服务器在通信前会进行公钥交换,双方会用对方公钥产生信息加密,对方公钥产生的加密只能由对方私钥进行解密。
-
[ 缺陷 ] 第三方虽然盗取公钥是无用的,但能够进行掉包,例如服务器在向客户端发送公钥的过程中,第三方将服务器的公钥掉包为自己的公钥,并伪装成服务器与客户端通信,从而截取了加密信息。
-
-
[ 数字证书 ]
-
[ 公钥认证 ] 非对称加密通信的缺陷在于无法确定接受到的公钥来自信息接受方,因此产生了一系列CA机构用于对公钥进行认证。
-
[ 数字证书 ] CA机构使公钥与数字证书绑定,数字证书会携带站点信息,公钥被篡改会导致与数字证书不匹配而不接受公钥,数字证书被篡改会通过其站点信息不相符而不接受公钥,数字签名是保存站点信息的方式。
-
-
[ 混合通信方式 ] 混合通信方式是非对称加密通信与对称加密通信的结合。 非对称加密通信虽然安全性有所保障,但其开销要更高。 对称通信的不安全主要来自于密钥交换,因此对于密钥交换采用非对称加密通信,完成密钥交换后,便可以采用对称加密通信方式进行正常的数据通信。
*8.1 [ TLS协议 ]
-
[ 概念 ] TLS(Transport Layer Security),传输层安全性协议。TLS由SSL演变而来,SSL起初仅是安全套接层,在SSL3.0后成为标准安全协议,并更名为TLS协议。
-
[ 结构 ] TLS共有两个子层级,记录层与握手层。 握手层包含四个子协议:握手协议(handsshake protocol),更改加密规范协议(change cipher spec protocol),应用数据协议(application data protocol)和警告协议(alert protocol)。 记录层仅有一个协议:记录协议(Record protocol)。
-
[ RSA握手 ]
-
[ 概念 ] TLS协议的RSA握手就是使用非对称通信方式产生交互对称加密通信密钥的过程,但有些许不同,这个过程有数字证书的加入。 我们知道HTTP协议建立在TCP通道之上,而TLS协议是HTTP协议下的协议,因此TCP三次握手建立TCP通道在TLS的RSA握手之前。 RSA握手过程完成了对称通信密钥生成与交换,在RSA握手中,需要通过RSA算法生成对称通信密钥,RSA算法需要确定密钥密码套件,凑齐client_random、server_random、pre_random三个随机数,使用三个随机通过密码套件生成密钥。 RSA握手之后,双方将进行对称加密通信。
-
[ 第一次握手 ] 客户端发出请求,包含一下内容: 使用的TLS协议版本, 能够支持的密码套件。 一个由客户端产生,用于生成密钥的随机数(clinet_random)。
- [ 状态 ] 协议版本:未确定 密码套件:未确定 客户端:client_random
-
[ 第二次握手 ] 服务器确认使用的TLS协议版本与使用的密码套件,如果服务器不支持客户端要求的TLS协议版本,则TLS握手过程结束。 服务器生成一个用于生成密钥的随机数(server_random),并将与公钥绑定的数字证书返回给客户端。
- [ 状态 ] 协议版本:确定 密码套件:确定 客户端:client_random 服务器:client_random、server_random
-
[ 第三次握手 ] 客户端验证服务器发送的数字证书,若存在风险则在页面中警告,由用户决定是否继续。 数字证书真实有效,则使用确定的密码套件生成另一个随机数(pre_random),并用服务器的公钥加密该随机数。 并将pre_random发送给服务器。
- [ 状态 ] 协议版本:确定 密码套件:确定 客户端:client_random、server_random、pre_random 服务器:client_random、server_random
-
[ 第四次握手 ] 服务器接受到pre_random,并告知客户端。 此时客户端和服务器达成了产生对称通信密钥的条件,双方会根据各自收到的三个随机数,以相同的密码套件加密方式,产生对称通信密钥。此后通信中的加密信息都需要使用该密钥进行解密。 双方中任意一方的任意一个random被劫持,都会导致生成的密钥与对方的不一致,从而对面使用该密钥加密的数据无法解密。 并且pre_random被服务器公钥加密,被劫持也无法解密,第三方无法凑齐三个随机数。
- [ 状态 ] 协议版本: 确定 密码套件:确定 客户端:client_random、server_random、pre_random 服务器:client_random、server_random、pre_random
-
[ 与对称加密通信的差异 ] 对称加密通信模型中,客户端与服务器都各自生成密钥,并为自己的信息用该密钥加密,共两个密钥。 而TLS四次握手中,密钥的生成也是由客户端与服务器各自生成的,但因为其生成的随机数与算法都一致,所以得到的密钥只有一个。
-
[ 与非对称加密通信的差异 ] 非对称加密通信中,服务器发送的信息会通过客户端的公钥进行加密,以确保仅有目标客户端能够获得该加密信息。但由于三个随机数缺一不可机制,即便server_random和client_random都被劫持,也无法获得密钥。 如果第三方尝试截取pre_random,以安全证书掉包的形式让浏览器用篡改的安全证书的公钥加密pre_random,浏览器会因为安全证书的数字签名与目标站点信息不匹配而不使用。
-
-
[ DH握手 ]
-
[ 概念 ] DH握手在RSA的基础之上,将pre_random通过DH算法产生,而DH算法需要通过server_params与client_params生成。
-
[ 第二次握手差异 ] 在服务器生成server_random并发送给客户端的第二次握手中,服务器还需要将生成的server_params用私钥签名并发送。
-
[ 第三次握手差异 ] 而第三次握手中,客户端在收到数字证书,server_random,还会收到服务器私钥签名的server_params,如果server_params被改动,则会因为签名性质而被客户端知晓,从而弃用。客户端也会生成client_params通过服务器数字证书的公钥进行加密,发送给服务器。因为DH握手中的pre_random是通过DH算法参数的,所以这个阶段客户端不会直接生成pre_random。
-
[ 第四次握手差异 ] 在这个阶段,服务器和客户端都有client_random、server_random、server_params、client_params,双方就会通过DH算法,用server_params与client_params生成pre_random,再通过RSA算法,用三个随机数生成密钥。
-
[ params截取 ] 服务器发送的server_params因为其用私钥签名而篡改无效,但会被第三方截取得知,但客户端的client_params通过服务器的公钥加密,第三方截取也无法解密。
-
9.[ HTTP协议迭代 ]
-
[ 迭代过程 ] 请求方法,报文格式等等这些概念并非在HTTP协议产生之初就产生的,而是随着HTTP版本迭代所产生。
-
[ HTTP/0.9 ] 这个时代的HTTP协议如其名称,超文本传输协议,只是服务于超文本的传输,其简单完成客户端获取超文本,服务器传输超文本两项任务。 因此请求在当时只是对超文本的请求,响应也只是对超文本的响应。自然不存在标头去说明请求和响应的信息,请求只是为了获取超文本,也不存在多样的请求方式,响应也只有成功传输超文本而失败传输超文本两种结果,自然不存在响应状态码。
-
[ HTTP/1.0 ]
这个时代的HTTP具备众多基本特征,请求方式,报文格式,缓存机制,响应状态码这些概念都逐渐产生。HTTP/1.0目前仍被广泛应用在代理服务器中。
-
[ 短连接 ] HTTP/1.0的TCP连接是短暂的,一次TCP连接对应一次请求响应,这意味着多次请求响应伴随频繁的TCP通道的连接与断开。
-
[ 请求阻塞 ] 在前一次请求未收到响应时,下一次请求将不允许被发出,这样的请求发起模式显然是低效的。
-
-
[ HTTP/1.1 ] HTTP/1.1是目前使用广泛的协议版本。
-
[ 持久连接 ] 请求标头的connection:字段能够建立一段持久的TCP连接,这段持久的TCP连接通过connection: keep-alive开启,通过connection: false关闭。这样避免了频繁请求引发的TCP通道频繁开关。
-
[ 管道化 ] 管道化建立在持久连接之上,管道化的请求不需要等待上一次请求的响应结果,就能够发出,可以在短时间发送多个请求。
- [ 响应有序 ] 管道化的响应是有序的,其需要与请求发出的顺序保持一致,当一组请求中某个请求迟迟没有响应,那么后续的请求也无法接受响应。 在管道化前,服务器仅能逐个处理请求,在管道化后,服务器能够批量处理多个请求,但客户端依然需要逐个接受响应。
- [ 多管道 ] 管道化建立于TCP持久连接,通过同时建立多个TCP持久连接,实现多管道请求,以提高请求效率。但客户端对于同时进行的TCP持久连接有数量限制,一般数量不超过10。
- [ HTTP队头阻塞 ] 响应有序引发的阻塞,从单一管道来看,会引发后续请求的响应阻塞,从多管道来看,一个管道出现阻塞,意味着有限的TCP通道数量被浪费了一条。一般这些问题都被称作HTTP的对头阻塞(Head of line blocking)
- [ TCP对头阻塞 ]
-
[ 多段响应 ] 标头的Transfer-Encoding字段能够启用多段传输机制,将一个请求的响应拆分为多段,往往在启用这种机制前,会通过标头的Content-length字段,确定数据大小。
-
-
[ HTTP/2.0 ]
-
[ 二进制帧(frame) ] HTTP/2.0以前的版本,报文的行与标头必须是文本格式,数据体可以是文本格式或二进制格式。 HTTP/2.0以后,报文在传输时为二进制格式,称为二进制帧。报文被转换为二进制帧后,被拆分为两部分,头信息帧与数据帧。
- [ 头信息帧(Headers frame) ] 相当于行,标头转换成帧后对应的内容。
- [ 数据帧(Data frame) ] 相当于主体转换成帧后对应的内容。
-
[ 二进制分帧层(Binary Framing) ] 二进制分帧层是一个HTTP协议下的层级,属于应用层内的层级,其作用就是完成报文与二进制帧的格式转换与编码。
-
[ 报文转换 ] 在传输前,报文会被转换为帧,能够直接转换为报文的完整帧称为消息。而帧在运输时会被拆分为更小的帧,通过字节流运输,每个被拆分的很细小的帧都会包含一个帧头部,去记录这个帧的信息,在拆分后的帧运输完后,帧会根据帧头部进行重新组合,得到消息,消息会再转换为报文。
-
[ 多路复用 ] 因为报文传输被拆分为帧传输,因此其传输是碎片的,无序的,从而不会像通道化传输那样,受限与响应的顺序。 请求和响应可以同时在TCP连接中进行传输,因为其都被拆分为细小的帧,从而真正意义上实现了双向数据流。
-
[ 标头压缩 ] 报文携带的标头信息,不会被直接代入在传输中,而是根据标头信息表,将完整标头信息用简单的标识索引号代替,这样在传输中,就可以用更简单的标识索引号代替完成的标头信息。
- [ 标头信息表 ] 启用HTTP/2.0的客户端与服务器之间会共同维护一张标头信息表,所有的字段都会在标头信息表上产生对应的标识索引号。
-
[ 服务器推送 ] HTTP/2.0的请求响应模型中,服务器不会自发向客户端发送数据,其发送数据需要由客户端像服务器请求,而HTTP/2.0允许服务器向客户端发送数据。
-
10.[ Cookie ]
-
[ 有会话无状态 ] HTTP协议是无状态的协议,其请求之间不存在关联,即服务器收到来自不同客户端的请求,并不能得知其是否来自不同客户端,因为这些请求都从同一url发出。
-
[ Cookie ] 当服务器需要区分来自不同客户端的请求时,服务器会将具有标识属性的Cookie,随着响应发送给客户端,并要求该客户端收到Cookie后,后续请求都必须携带Cookie。 因为Cookie需要具有标识属性,这样就能够通过客户端请求中携带的Cookie,区分请求来自哪个客户端,从而实现了有会话无状态的HTTP协议通信。
-
[ Cookie的创建删除 ] 服务器的响应标头的Set-Cookie字段,能够创建一个Cookie,并伴随响应发送给客户端。客户端一旦收到响应,其发送的请求会自动携带该Cookie在其标头,以Cookie字段携带。 当客户端关闭意味着会话结束,Cookie会被删除,在下次开启客户端时,服务器需要再次创建Cookie。 在网站使用中经常能够感知到Cookie的存在,当进入一个网站,网站会要求用户登录,用户进行登录后,服务器将登录后的数据返回的同时也返回了Cookie,也就确定了来自这个客户端对应的已登录账号状态,当用户关闭网页,再次进入网页,则需要重新登录。
-
[ 持久性Cookie ] 可以通过Expires属性或Max-Age属性,在Set-Cookie字段中,设置该Cookie的过期时间,这样会使Cookie作为持久的Cookie,不会随会话结束而删除。 在大部分具有登录功能的网站都是这样做的,在用户登录后,登录状态不会随关闭网页而退出,而是在一段时间后,要求用户重新登录。
11.[ 会话认证机制 ]
-
[ 概念 ] 在客户端完成服务器的身份认证后,服务器给客户端一个凭证,客户端在与服务器的数据通信过程中,每次请求都需要携带这个凭证,以让服务器知晓,该请求来自一个通过身份认证的客户端,凭证上面可以携带身份信息,让服务器知晓该请求的具体身份。
-
[ Cookie认证机制 ]
-
[ 概念 ] 早期在客户端完成身份认证后,服务器会直接将身份信息发送给客户端,客户端通过Cookie存储身份信息。这样客户端每次发起的请求,都会携带上身份信息,从而让客户端知晓请求是来自哪个客户端。
-
[ 缺陷 ] 这种方式存在明显问题。在客户端完成身份认证后,身份信息被直接交由客户端进行存储,这样不安全。如果Cookie携带的身份信息较多,每次请求都携带较多的身份信息会浪费网络开销。
-
-
[ Session认证机制 ]
-
[ Session ] Session是一个服务器上存储所有用户身份信息的数据集合,每个用户都会有一个SessionID,SessionID能够在Session中找到对应的身份信息。
-
[ 概念 ] 相比由Cookie直接存储携带身份信息不同,而是让Cookie存储一个简单的SessionID。在客户端完成身份认证后,服务器将SessionID发送给客户端,并让客户端的Cookie携带。这样就避免了身份信息直接存储在客户端,也避免了Cookie携带较多数据浪费网络开销的问题。因为服务器存储了用户的身份认证信息,所以相当于服务器帮忙管理客户端的状态,服务器是有状态的。
-
[ 缺陷 ] 如果客户端向服务器发送的请求中的Cookie携带的SessionID被篡改,那么服务器会根据错误的SessionID返回错误的身份信息。 如果站点含有多个服务器,这样在服务器集群中就需要共享session,其工程量较大。
-
-
[ Token认证机制 ]
-
[ Token ] 由三部分组成:用户身份标识,当前时间戳,数字签名。 数字签名能够防止uid的篡改,同时时间戳的加入,也可以更好的让服务器与客户端知道,当前会话是在什么时候完成的身份认证。
-
[ Token结合Sessino会话机制 ] 通过Cookie存储Token,让SessionID作为Token中的用户身份标识,这样能够加强SessionID的安全性。
-
-
[ JWT认证机制 ]
-
[ 背景 ] 伴随站点的规模不断扩大,站点不可避免的需要由服务器集群支持服务,而服务器集群的Session共享是不便的,因此对于身份认证逐渐往放弃session的方向发展,实现服务器无状态化。
-
[ JWT ]
-
[ 概念 ] JWT,全称JSON Web Token。由标头(Header)、携带信息(Payload)、签名(signture)三部分组成,但这三部分分别都通过Base64URL算法转换为三段字符串,并用.拼接为一个长字符串。因此JWT是由.拼接的三段字符串。JWT一般通过cookie携带。
-
[ 标头 ] 标头是一个JSON对象,表明了JWT的基本信息,其含有两个属性,属性alg对应的字符串,为签名使用的算法;属性typ的值固定为字符串'JWT',以表明这是一个JWT。
-
[ 携带信息 ] 携带信息也是一个JSON对象,该对象即是用户认证的身份信息。
-
[ 签名 ] 一般由服务器的密钥进行签名。
-
-
[ 作用 ] JWT能够安全的将用户认证后得到的身份信息伴随Cookie进行传递,让服务器可以去除session实现无状态化,将信息以JSON格式存储,通过Base64URL算法转为字符串传输,节省了网络开销。
-
12.[ 同源策略 ]
-
[ 概念 ] 同源策略是浏览器的核心安全功能,是必须的底层机制。当两个url的协议、域名、端口完全相同,则属于同源。违反同源策略会禁用xhr对象,从而导致基于xhr对象的HTTP请求不可发起。
-
[ 同源策略的作用 ] 同源策略是浏览器必须的底层,其限制了非同源的DOM操作与HTTP请求。 如果不限制非同源的DOM操作,那么黑客可以将他人的站点套壳在自己的站点中,去复制他人站点的DOM操作,在嵌套后的盗版站点进行。如果用户输入账户密码等隐私信息,就能被嵌套的站点截取。 如果不限制非同源的HTTP请求,当用户在站点进行操作时,点击了伪装的恶意站点链接,该恶意站点向目标站点发送的HTTP请求会携带用户的cookie,意味着来自用户的身份认证被盗用。
-
[ 违法同源策略的必要 ] 早期的站点规模小,一个站点由一个服务器维持运营,因此该站点的所有资源都来自同一个url下,当站点规模扩大 时,其可能由服务器集群维持运营,导致同一个站点的资源可能来自不同的url。当需要用户从站点当前的起点url,向目标资源所在的目标url发起请求时,会因为起点url与目标url不同源,而无法发起请求,从而导致跨域。
-
[ 源的继承 ] 这时会产生一个疑问,如果违反同源策略无法发起请求,那请求的起点url要怎么定义?源的继承指出,浏览器向站点请求访问站点,获取页面资源后,请求发出的起点url就会是目标站点的url。 即页面中通过about:blank或JavaScript:url执行的脚本会继承打开该url的文档的源。
-
[ 跨域实现方式 ]
-
[ CORS ]
-
[ 概念 ] CORS,全称Cross-origin resource sharing,译名跨域资源共享,是W3C标准定义的跨域资源通信方式,其实现方式是通过请求报文与响应报文的标头字段实现。该方式是普遍的跨域方式,是不考虑IE兼容的最优选。
-
[ 简单请求 ] CORS认为,一个请求的请求方式为HEAD,GET,POST其一,且请求报文的标头字段仅能有Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(限值为:application、x-www-form-urlencoded、multipart/form-data、text/plain),那么该请求为简单请求。
-
[ 简单请求跨域 ] 简单请求的标头需要用Origin字段,来告知服务器该请求的源,因此Origin字段的值为请求发起的起点url。Origin字段的值与请求的起点url不匹配会被浏览器驳回。 如果服务器允许来自该url的请求获取跨域资源,则服务器的响应需要在标头中通过Access-Control-Allow-Origin字段,值设置为允许的url,来允许来自该url的请求获取跨域资源,当该资源允许被所有url跨域获取时,Access-Control-Allow-Origin字段的值为*。 默认的简单请求跨域是不能使用cookie的,如果要求简单请求与其响应要使用cookie,则请求发出的xhr对象的withCredentials属性需要从默认值false更改为true,且服务器的响应标头需要将字段Acess-Control-Allow-Credentials值设置为true。
-
[ 非简单请求 ] 非简单请求的标头不仅需要Origin字段告知请求源,还需要Access-Control-Request-Method字段告知请求方法,因此该字段的值为请求方法,部分请求方法需要使用Access-Control-Request-Headers字段提供额外标头信息。 与之相对的,服务器的响应不仅需要Access-Control-Allow-Origin表明接受来自哪个url的跨域请求,还需要Access-Control-Allow-Methods表明接受来自运行的url的哪些请求方法,同时部分请求方法对应的响应也需要Access-Control-Allow-Headers字段额外提供标头信息。
- [ Preflight ] 非简单请求在正式发送前,会发送一个Preflight请求给服务器,Preflight请求使用OPTIONS方法发起,Preflight请求被响应后,才会发起非简单请求。响应标头的Access-Control-Max-Age字段,可以设置允许的源在多长时间内发起的非简单请求可以不用发起Preflight请求。
-
-
[ JSONP ]
-
[ 概念 ] 同源策略中限制非同源的DOM操作与网络请求,但允许跨域资源引用,JSONP实现的跨域就是利用这一特点。而通过script标签获取引用资源,是不会触发同源策略的,因此可以通过script标签包装。该方式只能发送get请求方法的跨域请求,且并非是官方标准的跨域方式,一般用于解决IE下的跨域问题。
-
[ 过程 ]
<script src="http://localhost:8080/getData?callback=JSONPCallback" >通过script标签,向url为http://localhost:8080/getData请求一个JavaScript脚本,该请求为get请求,且响应结果只能为js,不触发同源策略。 该url的?后紧跟一个回调函数,该回调函数为提前写好并提供的JSONPCallback,以方便接受数据。
const JSONPCallback = (data) => { console.log('结果:' + data) }JSONPCallback会接受一个参数,该参数即是服务器返回的结果。
-
-
[ 图像ping ]
-
[ 概念 ] img标签的src属性与script标签的src属性一样,即使src属性的url是非同源的,也运行发出请求,但由于img标签的限制,其请求的结果只能是图片。
-
[ 作用 ] 通过图像ping可以简单的跨域获取图像资源,同时img标签对应的DOM提供了.onload与.onerror两个API,当图片加载成功触发onload,图片加载失败触发onerror。 图像ping结合onload可以实现用户观看图片的计数功能,从而实现计数用户广告阅览次数的业务需求。
-