一、引言
在互联网和软件工程领域,通讯协议是绕不开的话题。协议不能没有HTTP,就像西方不能失去耶路撒冷。
HTTP(超文本传输协议,Hypertext Transfer Protocol) 是一种用于从网络传输超文本到本地浏览器的传输协议。
HTTPS(超文本传输安全协议,Hypertext Transfer Protocol Secure) 是 HTTP 的安全版本,它在 HTTP 下增加了 SSL/TLS 协议。
面试再有人问二者的区别,第一句话就是:HTTPS是HTTP的安全版本。
二、预备知识
1、计算机网络模型
常见的计算机网络模型说法有两种:OSI七层模型;TCP/IP模型。
-
应用层:计算机各类应用例如QQ邮箱、微信便建立在应用层。HTTP是应用层的常用协议。
-
表示层:负责用户展示的数据的编解码等,例如将JPEG格式的文件解析成图片
-
会话层:负责向用户进程建立连接并有序传输数据等,例如浏览器的多个标签页,各自展示文字、音频、视频互不影响。
-
传输层:负责两个进程间的通信,主要协议有TCP、UDP。
-
网络层:负责把数据在两个物理节点间传输,例如IP协议,路由器相关功能。
-
数据链路层:负责将数据组装成帧,供物理层传递。
-
物理层:在媒介中传输比特流,换种说法就是在网线中传输电信号。
以上7层结构自上而下逐层封装,每一层都会添加各自的标识和信息,再另一端逐层拆装。
建议直接记住7层模型,TCP/IP模型只是把各层组合了一下,有一个口诀方便记忆:物联网淑慧试用
物(物理层)联(数据链路层)网(网络层)淑(传输层)慧(会话层)试(表示层)用(应用层)
因此,我们说HTTP是应用层的协议,基于传输层的TCP协议。
2、数据加密
-
对称加密
通信双方共用一个密钥进行加解密。
举一个通俗易懂的例子:A给B传递圆周率的大小,但是不想明文传递,于是双方约定每一位数字减一,便有了这样的密文。
3.1415926 --> 2.0304815
B收到后再每一位数字加1,就可以得到原来的数据。
经典的对称加密算法有AES、DES等。
-
非对称加密
由于对称加密比较简单,密钥一旦被在传输过程中被拦截,黑客就能知道密文对应的原文,因此对称加密安全性不高。
非对称加密算法需要两个密钥:公开密钥(public-key : 简称公钥)和私有密钥(private-key : 简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。
因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
非对称加密等于是A给了B一个挂着🔓的箱子(传递公钥),B收到后把消息装进箱子并关上了🔒(加密),再把箱子传回A(发送消息)。此时消息链路上即使有黑客,也无法打开锁。因此实现了更高一级的消息加密。当然,非对称加密也无法完全避免中间人攻击,后续会讲到。
三、HTTP协议
-
协议结构:
HTTP请求格式:请求行(Request Line)、请求头(Request Headers)、空行 和 请求数据 四个部分组成。
GET /index.html HTTP/1.1 Host: www.baidu.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate Connection: keep-alive {Request Data ……}
HTTP返回格式:状态行(Status Line)、响应头(Response Headers)、空行 和 返回数据 四个部分组成。
HTTP/1.1 200 OK Date: Wed, 18 Apr 2024 12:00:00 GMT Server: Apache/2.4.1 (Unix) Last-Modified: Wed, 18 Apr 2024 11:00:00 GMT Content-Length: 12345 Content-Type: text/html; charset=UTF-8 <!DOCTYPE html> <html> <head> <title>Example Page</title> </head> <body> <h1>Hello, World!</h1> <!-- The rest of the HTML content --> </body> </html>
-
请求方法(Method)
-
GET、POST,在业务逻辑中使用较多。
-
PUT、DELETE,在工具类软件开放接口中会使用到。例如Teambition中参与人编辑、Jira系统的BUG状态更改、静态代码扫描平台SONAR的扫描结果编辑。
-
OPTIONS,预检请求,客户端将自己要请求的类型和内容提前询问服务端,服务端告知是否接受。大多在跨域场景下使用,后面再会再专门总结下跨域相关的内容。
-
HEAD,类似于 GET 请求,但服务器不返回请求的资源主体,只返回响应头。HEAD 请求通常用于获取资源的元信息,如资源的大小、类型等,而不需要获取资源的实际内容。
HTTP标准中还有CONNECT、TRACE、PATCH方法,在业务逻辑中使用较少。
-
-
状态码(响应码)
通常可以根据服务端返回的HTTP响应码判断HTTP请求结果,在接口自动化工具中我们使用了org.springframework.http库获取HTTP状态码。
平时所说的200(OK)、404(Not Found)、502(Bad Gateway)就代表了不同的状态含义。分类如下:
-
1xx(信息性状态码):表示接收的请求正在处理。
-
2xx(成功状态码):表示请求正常处理完毕。
-
3xx(重定向状态码):需要后续操作才能完成这一请求。
-
4xx(客户端错误状态码):表示请求包含语法错误或无法完成。
-
5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误。
a. 在日常工具开发中,偶有上游提供的接口会返回 3xx 的状态码,我们使用的HTTP库例如org.apache.httpClient就需要对其进行特殊处理。但Spring自带的RestTemplate就无须额外处理。
HttpClientBuilder builder = HttpClients.custom() //关闭自动处理重定向 .disableAutomaticRetries() //利用LaxRedirectStrategy处理POST重定向问题 .setRedirectStrategy(new LaxRedirectStrategy());
b. 4xx代表客户端错误,404 Not Found 代表请求的资源不存在,一般常见于路径错误。405 Method Not Allowed代表方法错误,POST接口使用了GET请求。
c. 5xx代表服务端错误,后端服务崩溃等情况。
-
-
User-Agent
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0
-
Mozilla/5.0 是一个通用标记符号,用来表示与 Mozilla 兼容,这几乎是现代浏览器的标配。
-
platform 用来说明浏览器所运行的原生系统平台(例如 Windows、Mac、Linux 或 Android),以及是否运行在手机上。搭载 Firefox OS 的手机仅简单地使用了 “Mobile” 这个字符串;因为 web 本身就是平台。注意 platform 可能会包含多个使用 "; " 隔开的标记符号。
-
rv : geckoversion 表示 Gecko 的发布版本号(例如 “17.0”)。在近期发布的版本中,geckoversion 表示的值与 firefoxversion相同。
-
Gecko/geckotrail 表示该浏览器基于 Gecko 渲染引擎。
-
在桌面浏览器中,geckotrail 是固定的字符串 “20100101” 。
-
Firefox/firefoxversion 表示该浏览器是 Firefox,并且提供了版本号信息(例如 “17.0”)。
-
-
Accept-Encoding
客户端用来向服务端约定数据压缩方式的,以减小数据体积。客户端以Accept-Encoding枚举可接收的压缩方式,服务端通过Content-Encoding返回最终确定的压缩方式。
在抓包代理工具中,往往需要根据拦截的Content-Encoding,正确解压数据,展示给用户。
/** * Gzip解压缩 */ public static String unGZip(InputStream inputStream) throws IOException { try (final GZIPInputStream gzipInput = new GZIPInputStream(inputStream); final StringWriter stringWriter = new StringWriter()) { IOUtils.copy(gzipInput, stringWriter, UTF_8); return stringWriter.toString(); } catch (IOException e) { throw new UncheckedIOException("Error while decompression!", e); } }
-
Connection
我们经常会见到对HTTP的描述:无状态、无连接的协议,其中无连接其实是指HTTP1.0默认使用短连接。由计算机网络结构可知,HTTP是基于TCP的应用层协议,TCP的连接模式是经典的“三次握手,四次挥手”,每一次连接的建立,都有一定的开销。
HTTP1.0是建立连接 --> 传输数据 --> 断开连接,每次传输数据时都需要重新建立连接。因此性能耗费比较大。
HTTP1.1改进为连接复用,传输完数据后,继续保持连接,下次数据传输可直接使用建立好的连接。
因此,HTTP1.0默认是短连接,如果需要使用长连接则需设置
Connection:keep-alive
HTTP1.1默认长连接,如果需要使用短连接则需设置
Connection:close
-
Content-Length
用于表示请求/返回的数据长度(字节数),防止数据被篡改。在使用fiddler和mock工具时,如果将返回头的Content-Length字段手动设置,并且和返回体的长度不一致,客户端页面会报错。
-
Content-Type
用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些网页点击的结果却是下载一个文件或一张图片的原因。
常见的媒体格式类型如下:
- text/html: HTML格式
- text/plain:纯文本格式
- text/xml: XML格式
- image/gif:gif图片格式
- image/jpeg:jpg图片格式
- image/png:png图片格式
以application开头的媒体格式类型:
- application/xhtml+xml:XHTML格式
- application/xml: XML数据格式
- application/atom+xml:Atom XML聚合格式
- application/json: JSON数据格式
- application/pdf:pdf格式
- application/msword: Word文档格式
- application/octet-stream: 二进制流数据(如常见的文件下载)
- application/x-www-form-urlencoded :body中的格式:key1=val1&key2=val2,如果是中文或特殊字符如"/“、”,“、”:" 等会自动进行URL转码。
另外一种常见的媒体格式是上传文件之时使用的:
- multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
在工具开发中,Spring框架使用MessageConverter针对不同的Content-Type会自动编解码。
四、HTTPS协议
之前说到,HTTPS相较于HTTP最大的特点就是安全,那么HTTPS究竟为何安全,原因主要是两个关键词: 加密 和 证书。
-
中间人攻击
一个黑客将自己伪装成双方的交流对象,进行消息截获和消息篡改
-
非对称加密 + 对称加密
由于有“坏蛋”的存在,消息不能使用明文在链路中传递,因此需要对通信进行加密:
- 对称加密。速度最快,性能消耗较小,最简单。但是公钥也会被中间人监听,导致可以轻松解密。
- 非对称加密。速度较慢,性能消耗很大,较复杂。但是每一次发送消息都要使用公钥加密,对方私钥解密,使得通信变慢。
- 非对称加密 + 对称加密。既然对称加密的公钥容易被监听,那就先把公钥进行非对称加密!双方都安全的获得了对称加密的公钥之后,再进行对称加密的通信。(真不知道谁想出来的,我只能说一句🐂🍺)
-
数字证书
有了上述的方式,就能避开“中间人攻击”了吗?好像并不完全能。如果中间人在每一步都截获了公钥,就能和B通信,再生成一个自己的公钥私钥,伪装成B,和A进行通信。因此,在第一步中A能不能验证B传过来的公钥是“真的”就非常重要,HTTPS引入了数字证书机制。
-
证书认证机构属于是具有权威的第三方,此类证书会被浏览器直接验证通过,当然,用户通过认证机构生成证书也是要交费的。
-
浏览器会验证证书中的有效日期、颁发机构、域名与访问的地址一致等信息。
-
用户可自行生成证书,但是浏览器会识别出来并且提示访问者该网站证书不受信任。在我们使用fiddler或charles抓包时都手动进行过“信任”操作,其原因也是代理抓包软件自己生成了证书,需要手动信任后才能继续通信。当然这种情况下抓包工具已经属于“中间人”了,但是是我们信任的操作,所以是安全的。
-
我们可以在访问HTTPS站点时,点击浏览器地址栏左侧的🔒,查看该网站的证书:
-
五、区别总结
HTTP | HTTPS | |
---|---|---|
端口 | 80 | 443 |
加密 | 不加密,安全性差 | 加密:SSL/TLS |
证书 | 无 | 数字证书 |
性能 | 响应速度快 | 响应速度慢,资源耗费较多 |
SSL/TLS实际上就是HTTPS中加密、证书认证的一整套流程方式,在前两个小节中已经给大家拆解分析了,有兴趣大家可以自行拓展下~
六、参考文档
MDN Web Docs https://developer.mozilla.org/zh-CN/docs/Web/HTTP
菜鸟教程 https://www.runoob.com/http/http-tutorial.html
王道考研 计算机网络 https://www.bilibili.com/video/BV19E411D78Q