我们在之前的章节中已经初步了解了协议,所谓协议就是指我们的一种“约定”,现在,让我们自顶而下的去探究我们各个层级的协议,我们先从应用层的HTTP协议开始
HTTP协议的概念
在我们了解HTTP之前,要先明确我们几个必要的概念
HTTP(HyperText Transfer Protocol,超文本传输)的协议
HTTP是无连接,无状态,服务于应用层的协议
这里的无连接我们可以理解为:HTTP协议本身没有维护连接信息,HTTP会交给网络协议栈传输层的TCP协议,而TCP协议则是面向连接的
无状态我们可以理解为:HTTP协议自身不对请求与响应之间通信之间进行保存,也就是说在HTTP这个级别,协议对于发送过的请求或相应都不做持久化处理
那么HTTP既然是无连接的,不会维护连接信息,那么它是否是可靠传输呢?
事实上,HTTP虽然无连接,自身不会维护连接信息,但是,它的数据最终会交给传输层的TCP协议,而TCP协议是可靠传输的,因此HTTP协议是可靠传输的
认识URL
我们平时俗称的“网址”就是URL,我们来对URL进行剖析
http:明文传输,默认端口号位80
https:加密传输(一般使用ssl非对称加密方式,会对http双方发送的数据进行加密,公钥:客户端持有的通常用来加密,私钥:服务端持有,通常用来解密),默认端口是443端口
urlencode与urldecode
在我们的url中,/?:等等这样的字符都被赋予了特殊的意义,因此这些字符不能随意的出现在url中,而如果想要使用这些符号,就需要转义,对特殊字符的转义就被称为urlencode
转义规则:将要转义的字符转化为16进制,然后从左到右,去掉4位(不足四位直接处理),每两位做一位,前面加上%,编码成%XY的格式
而我们的urldecode就是将16进制数据转化为字符
我们可以看到,当我们搜索C++时,++符号被解释成了%2B,这就是urlencode与urldecode在进行转义
HTTP协议的数据流
HTTP协议格式
HTTP请求
HTTP请求规定,请求从客户端出发,服务器端相应该请求并返回,请求一定是从客户端发起开始建立通信的,服务端在没有收到请求之前是不会发送相应的,请求格式如下图
我们可以看到
首行 : [ 方法 ] + [url] + [ 版本 ]Header: 请求的属性 , 冒号分割的键值对 ; 每组属性之间使用 \n 分隔 ; 遇到空行表示 Header 部分结束Body: 空行后面的内容都是 Body. Body 允许为空字符串 . 如果 Body 存在 , 则在 Header 中会有一个Content-Length属性来标识 Body 的长度 ;
注意:分离正文与报头的标志是存在一个空行,\r\n,我们HTTP是按行读取,若读到空行,则代表下方就是正文,而正文的数量存储在报头中Content-length行中,而后读取相应大小的字节数即可获取正文内容
HTTP的方法
其中最常用的就是GET方法和POST方法.,也就是我们的访问与上传方法
http1.0是短链接,http1.1是长链接
http的状态码
最常见的状态码, 比如 200(OK), 404(Not Found), 403(Forbidden), 302(Redirect, 重定向), 504(Bad Gateway)
这些状态码其实我们已经有所了解了,就比如当我们网络不好时访问网页得到404
不过我们再对其他的状态码做补充
永久重定向:想进入到一个网页,直接跳转到另一个网页,彻底忘记之前网页的存在
临时重定向:先进入到旧的网页,服务器返回响应实际要跳转到另一个网页,客户端再去链接实际要跳转的网页
http常见Header(报头)
Content-Type: 数据类型 (text/html 等 )Content-Length: Body 的长度Host: 客户端告知服务器 , 所请求的资源是在哪个主机的哪个端口上 ;User-Agent: 声明用户的操作系统和浏览器版本信息 ;referer: 当前页面是从哪个页面跳转过来的 ;location: 搭配 3xx 状态码使用 , 告诉客户端接下来要去哪里访问 ;Cookie: 用于在客户端存储少量信息 . 通常用于实现会话 (session) 的功能
cookie和session
这里我们先来介绍一下我们的cookie,我们知道,http协议是无状态的,并不会记录用户的信息,但是我们实际生活中使用网页需要登陆时,一般我们登陆了一次,再次进入时是不需要登陆的,因为http本身是无状态的,如果我们频繁的访问某个页面且每次都需要登陆,那么此时我们的用户体验就会不好
为了解决这个问题,我们的cookie诞生了
cookie原理:
当浏览器访问某种资源进行登录时,客户端会将我们的账号密码数据发送给服务器,服务器与注册时保存的name与passward进行对比,成功后相应,将name与passwd放在报头的set-cookie中发送给客户端,客户端将其保存在cookie中,下次访问时将cookie信息发送给客户端就不需要登陆了,其实我们的cookie本质就是一个浏览器文件,之中保存着用户的信息
补充:文件保存是分为内存级或者硬盘级的,我们将登录信息保存在内存中时,当我们使用完毕浏览器关闭进程后,再次想登录同样一个网站,此时我们就会发现,仍然需要二次登录,这就是cookie放在内存中,当进程退出,资源释放,内存被清空,我们所保存的登录信息也就被清空了;我们将登陆信息保存在硬盘中时,当我们登陆过后,即使将电脑关闭,再次启动时进入界面仍然不需要再次进行登录,他自动保存了登陆数据,这就是因为cookie保存在了硬盘中,得到了长久地保存
但是我们使用cookie保存用户数据并不是安全的,中间人只需要截取我们的报头cookie字段就能将数据窃取,所以我们出现了session
session原理:
在本地保存用户的信息,发送时候并不安全,于是在客户端进行登录时,将name与passwd发送给服务器,服务器形成了一个sesion文件,里面存了一个sid,全网唯一一个用以标识用户的信息,,相应时我们只需要将sid放在set-cookie中发送给客户端,客户端将sid保存在cookie中,下一次访问set-cookie中中保存的sid,服务器只需要拿到sid进行比较即可
我们在name与passwd外层嵌套了一个sid进行识别,这样安全性就会提高一点
Cookie与Ssion的区别
cookie数据存放在客户的浏览器上,session数据放在服务器上。
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session。
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE。
单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。
所以:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中。
http和https对比
http的端口号是80,https协议端口号的443。
其实我们http与https最大的区别就在于https中相对于http的4层模型多加了一层安全层SSL/TLS,起到了对数据进行加密与解密的作用
SSL:非标准的;TSL:标注的
所以相对于http而言,https更加安全
加密解密
对称加密:对称加密存在一个密钥,使用同一个密钥进行加密与解密操作
非对称密钥:非对称密钥有两个,一个是公钥,一个是私钥,通常情况下使用公钥进行加密,使用私钥进行解密,不过在特殊的情况下我们使用私钥加密公钥解密也是可行的
但是此时会有一个问题,我们的客户端与服务器端都需要密钥来进行加解密,密钥也需要进行传输,也是数据,也需要保证密钥的安全,所以我们为了保证密钥的安全,采用非对称加密来对密钥进行保护
我们为什么存在了更加安全的非对称加密,还需要对成加密呢?
事实上,我们更多的数据都是采用对称加密的方式来进行保护的,原因只有一个,那就是对称加密算法更加简单,效率更高
但是我们又需要保证数据的安全,所以我们只需要对密钥进行非对称加密,对其它部分进行对称加密来完成
但是,此时我们碰到的黑客更加厉害了,直接在中间搭建中间服务器,来对我们的公钥与私钥进行截取,间接访问服务器
那么我们的服务器又是如何应对这样的的问题呢?
中间信息被修改?
服务器端收到客户端发来的信息,响应会将响应信息通过哈希算法对响应数据进行映射,得到一个定长字符序列,这个定长字符序列被称为数据摘要。服务器将数据和数据摘要一起发送给客户端,并且都进行了加密。数据加密通过秘钥进行加密,数据摘要加密是通过公正部门的秘钥进行加密,中间人获取不到这个秘钥。数据摘要加密后称为数据签名(指纹)。
当客户端收到数据,只要将摘要解密,将数据通过相同哈希算法或一个数据摘要,再和发送来的数据摘要进行比较,相等说明没有被窜改。
中间服务器修改数据同时还得修改数据摘要,但是无法解密数据摘要,即使对数据进行修改,客户端也能识别。
远端服务器认证?
远端服务器有公正部门的证书,证书中包含权威信息,中间服务器没有。发送时将权威信息通过哈希算法映射成数据摘要,将证书和数据摘要通过私钥加密,发送给客户端。
客户端内置证书信息,可以用公钥解密,将权威信息进行比较,来识别远端服务器。
中间服务器无法获取权威信息的数据摘要,数据摘要进行加密了。