【Linux】应用层协议http
一. HTTP 协议介绍
HTTP(HyperText Transfer Protocol)超文本传输协议,是互联网中客户端与服务器传输的协议。HTTP 无连接无状态,每次请求都是独立的,每次请求都要重新创建新链接,需要 session 和 cookie 保存登陆信息状态;始终由客户端发送请求,服务端不会向客户端发送请求;可以传输多种数据格式,音频视频图片等等。
二. HTTP 协议工作过程
当我们在浏览器输入一个网址时,此时浏览器会给服务器发送一个 HTTP 请求,服务器收到这个请求之后,经过计算返回一个 HTTP 响应。
客户端是主动访问的一端发起请求的一端,服务端是被动接受请求的一端,请求是客户端发送给服务端的数据,响应是服务端返回给客户端的数据。
三. HTTP 协议格式
了解了 HTTP 就是网络通信的协议之后,我们来大致看看协议请求和响应的协议格式
请求格式:
请求格式包含请求方法,url,http版本,请求报头,以及正文;其中元素之间用空格和换行符隔开,用于区分不同元素,用于解决粘包问题。
响应格式:
响应格式包含 http版本,状态码,状态码描述,响应报头,响应正文。
四. HTTP 协议请求(Request)
下面我们来逐一介绍请求中的元素
4.1 url
URL(Uniform Resource Locator)统一资源定位符,简单说就是我们日常生活中的网址,我们通过这个唯一的url就能访问到特定的资源。
URL 由六部分组成,我们先放上一个网址
http://www.example.com:8080/product/list?category=book&page=1#top
首先是http,规定url获取资源的方式,类似的方式还有https,ftp等;www.example.com 相当于门牌号,通过这个门牌号我们可以解析出具体的ip地址,后面的8080就是对应的端口号;/product/list 就是在该地址的根目录下所要访问的具体文件;接下来就是客户端向服务端传递的参数,由?进行划分,传递第一个参数category = 1,第二个参数page=1,参数之间用&分隔;最后是片段,用#分隔,用来定位网页的具体位置。
4.2 认识method
核心请求方法有五种,GET,POST,PUT,DELETE,PATCH;我们日常使用的GET,POST占比最高。
4.2.1 GET
GET 的核心是从服务器中要东西,参数会拼在url当中,因此我们肉眼就可以看见,它的安全性不高,容易暴露参数信息
https://api.example.com/users?id=123
如此处我们想访问 id = 123 的用户
4.2.2 POST
POST 的核心是向服务器发东西,参数存放在正文中,URL看不见;例如我们登陆输入账号密码
https://www.example.com/login
此时我们输入的账号密码会保存在正文当中,不会在url上显示,因此安全性较高。
4.3 认识请求“报头”
请求报头用于说明,例如说明客户端浏览器类型,可接受数据格式,是否缓存,是否长连接等。
下面是一些常见报头
cookie:携带客户端本地存储的信息,用于记录用户偏好,登陆状态信息等。
content-type:指定正文格式,是传表单数据,JSON数据还是文件上传等等
content-lengt:请求正文字节数
accept:可接受的内容类型,JSON格式HTML格式等等
host:请求的主机名和端口号
referer:告知当前的请求从何处跳转
4.4 HTTP 版本
HTTP 有很多版本,HTTP1.0 HTTP1.1 HTTP2.0 等等。
HTTP1.0 支持GET,POST等多种方法,但是只能建立短连接,每次访问都要重新建立新连接。HTTP1.1 在HTTP1.0 的基础上支持了长连接,客户端可以一次发送多个请求,不需要没发送一个请求建立一次连接,大大增加了效率。
五. HTTP 协议响应(Response)
5.1 状态码
状态码是服务端给客户端的实际反馈,任务是否成功失败的原因是什么等等。
任务码分为五类。它们分别由1,2,3,4,5开头
1xx:表示服务器已经接收请求正在响应
100:上传大文件时,服务端告知客户端继续上传
2xx:服务器成功处理数据返回
200:服务器成功返回网络内容
201:服务器文章创建成功
204:删除文章后服务器表示无内容返回成功
3xx:请求资源位置变更
301:永久重定向,访问的资源永久更改位置
302:临时重定向,访问的资源临时更改位置
4xx:客户端存在错误
400:填写表单不正确错误返回
401:访问登陆页面时未登录访问失败
403:尝试访问没有权限的页面
404:访问不存在的网络连接
5xx:服务端存在错误
500:服务器崩溃,数据库崩溃
5.2 响应报头
响应报头的主要作用是告知客户端如何处理数据,或传递服务相关信息。
下面是一些常见报头
content-type:指定正文格式,是传表单数据,JSON数据还是文件上传等等
content-lengt:请求正文字节数
content-encoding:告知客户端正文使用的压缩格式
location:指定重定向,告知客户端需要跳转的新url
六. Cookie 与 Session
6.1 Cookie 工作原理与用途
Cookie(小饼干)通常用来记录服务器发送到浏览器的一小部分数据,这份数据在浏览器中保存下来,它同来记录一些用户信息,用户偏好等等。
当用户第一次访问网站时,客户端会在 set-cookie 报头中存储用户的信息,类似账号密码等;用户将数据传给服务器,服务器将这份数据传回给客户端浏览器,并在本地浏览器保存下来。在之后的请求当中,每当向这个网站申请访问时都会自动带上这份数据。
如我们打开一个浏览器,随意一个网站左上角处可以找到一把锁,点开里面的Cookie和站点数据,内部就存储着浏览器记录的用户在当前网站的一些信息偏好。
有了Cookie的存在,当我们使用一些登陆平台时不再需要每打开一次网址就登陆一次,浏览器保存了用户的账号密码,每当用户访问该网站时,客户端会携带Cookie信息一同发送给服务端。
当然Cookie也存在着安全隐患,由于Cookie存储着本人特有的信息,如若被不法之人恶意窃取,通过一些技术脚本获得到我们的Cookie信息,那么它们就可以拿着这些信息冒充我们的身份去访问服务器
6.2 Cookie 格式
Cookie格式分为请求头 Cookie 格式和响应头 set-cookie ,它们的参数都很类似,我们就选 set-cookie来介绍
Set-Cookie: name=value; [属性1=值1]; [属性2=值2]; ...
其中name=value 是必选选项,其余属性都可以自由选择,每个属性之间用分号+空格隔开。其中的name可以是用户姓名,主题颜色,登陆状态等,value就是键值对应用户id,颜色,登录情况。
Expires:
设置Cookie过期时间,决定了Cookie的生命周期,采用格林威治时间,格式如下
Expires=Wed, 21 Oct 2026 07:28:00 GMT 星期几 日 月 年 具体时间 这几部分组成
Domain:
设定特定的访问域名,该份Cookie数据只有访问该域名时才会生效
Domain=.example.com
Path:
指定访问该域名下的特定路径,我们只能访问根目录下的某一个特定的文件夹
Path=/admin
Secure:
设定仅允许https协议下才允许携带,否则不通过,此处只需填写用户名
Secure(无值,仅写属性名)
6.3 Session 工作原理
Cookie虽好,但是它会将用户信息暴露出去,如果是一些账号密码,很容易被一些脚本软件窃取,所以我们需要通过session与其进行配合
用户首次访问服务器时,服务器会为其分配一个特定的session id,并开辟一块空间储存用户的session id,通过 set-Cookie 将session id传回给客户端,当客户端再次访问时,就是通过Cookie传递 session id 访问网站。这样避免了将敏感信息暴露在外部,而是使用session id 这种无实际意义的值进行了替代。即使它人拿到了session id,也需要进行解密才能使用,增加了安全性。
七.HTTPS协议原理
https 和 http 的区别在于https存在一层保护协议,保证了我们传输的数据不被中间人随意篡改。
常见的加密方式对称加密和非对称加密。对称加密只有一份密钥,客户端用该密钥进行加密,服务端再拿着该密钥进行解密;非对称加密需要两份密钥,一份公钥一份私钥,我们可以使用公钥加密私钥解密,或者私钥解密公钥加密。
接下来我们来探寻一下各种加密方法的可行性
方法一:只使用对称加密
双方都只存在一份密钥,若密钥没有被破解,那么双方的通信就是安全的。但是服务端不仅仅是和一个客户端进行通信,若客户端数量多,那就需要每个客户端维护一份密钥,大大增大了维护成本。或者在传输的时候临时确定一个密钥,那么这份密钥就需要进行加密传输,若明文传输就会被中间人获取,所以要对密钥进行加密操作,所以又再次绕回了。这个方法行不通
方法二:只使用非对称加密
若只使用非对称加密,只能保证有一方传递的数据是安全的。假如客户端用公钥加密私钥解密,那么服务端传递给客户端的信息就是安全的,服务端用公钥加密后只有客户端用私钥才能进行解密。但客户端传数据给服务端时,用私钥加密公钥解密,若中间人获取了公钥,那么就能拿着公钥对数据进行解密篡改,因此存在风险。
方法三:双方都使用非对称加密
若用两份公钥和私钥看似较为安全,因为非对称加密只能保证一端是安全的,那么用两份不就两端都安全了吗。其实不然,两方都使用非对称加密首先效率大大降低,一次通信就涉及到4次加密解密操作,其次若每个客户端需要一份密钥,那么服务端管理成本也相继增加。
方法四:使用对称加密和非对称加密
首先服务端先将公钥s传递给客户端,客户端用该公钥对密钥c进行加密传回给服务端,这样服务端和客户端就有了同一份密钥。
若中间人截取了服务端的公钥,将自己伪装的公钥m传给客户端,客户端用m进行加密后传给服务端时,中间人用私钥m进行解密,这样就获得了客户端的密钥。所以这样也是不安全的
问题的本质在于我们传输的信息无法确定是否被中间人进行了篡改。既然两个人无法解决,那么我们就申请引入第三者。
这里我们引入CA证书
服务端在使用HTTPS之前,需要向CA机构申请一份数字证书,数字证书里包含申请者信息,公钥信息。服务器把证书传给浏览器,浏览器从中获取公钥,证书就如同身份证,证明服务端公钥的权威性。
在申请证书时,会把公钥和私钥发送给服务器使用

有了证书,我们还需要一份数据签名,确保数据没有被私自篡改
我们首先对数据进行散列函数得到一个散列值,用签名者私钥进行加密这个散列值;最后服务端拿到数据进行散列函数得到散列值,并对加密的散列值进行公钥解密最后比对两份散列值是否相同就可以判断内容是否篡改。
方法五:非对称加密+对称加密+证书认证
服务端与客户端连接后,服务端给客户端传递一份证书,证书包含公钥和服务端域名。客户端拿到证书会对证书进行校验。对签名解密得到一份hash值,对证书散列化得到第二份hash值,两份hash值比对就能确定证书是否更改。