(面试)HTTP

HTTP

概念:

HTTP为超文本传输协议,是一个在计算机网络中专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的应用层的规范。

长连接和短连接:

长连接:长连接,指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。

短连接:短连接是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。

长连接与短连接对比:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误, 频繁的socket 创建也是对资源的浪费。而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,服务器会被耗尽,所以并发量大,但每个用户无需频繁操作情况下需用短连好。

HTTP 1.0/HTTP1.1/HTTP2.0对比

HTTP1.1对比HTTP 1.0:

  • HTTP1.1默认使用长连接
  • HTTP1.1可以断点续传,允许请求资源的某个部分
  • 增加了一些错误状态码
  • 在1.0的基础上加入了一些缓存的新特性

HTTP2.0对比HTTP 1.X:

  • HTTP2.0和HTTP1.X都是基于TCP/IP进行通信的。但是HTTP2.0通过在传输层(TCP)之上增加了二进制分帧层,方便传输
  • 多路复用,一个连接可以同时传输多个Request,服务器端通过Request_id对请求进行分辨
  • Header压缩,HTTP2.0采用Hpack算法对请求的Header进行压缩,服务器和客户端双方各自维护一份缓存HeaderFiled表避免header重复传输
  • 服务器推送,http2.0能通过push的方式将客户端需要的内容预先推送过去

HTTP常用的请求方式:

GET请求、Request请求、Delete请求

GET与Request区别:

GET在url后加上请求参数,但是浏览器对URL长度有限制,Request在数据包内进行传输

GET相对Reques没那么安全

GET请求只能进行URL编码,Reques支持多种编码格式

GET请求效率高

HTTP请求体与响应体:

HTTP的请求报文包括:请求行(request line)、请求头部(header)、空行 和 请求数据(request data) 四
个部分组成

请求行: 请求方法,URL(包括参数信息),协议版本这些信息(GET
/admin_ui/rdx/core/images/close.png HTTP/1.1)

请求头:是一个个的key-value值,比如Accept-Encoding: gzip, deflateUser-Agent:
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR
2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)

空行(CR+LF):请求报文用空行表示header和请求数据的分隔请求数据:GET方法没有携带数据, POST方法会携带一个body

HTTP的响应报文包括:状态行,响应头,空行,数据(响应体)

状态行:HTTP版本号,状态码和状态值组成。

响应头:类似请求头,是一系列key-value值Cache-Control: privateContent-Encoding: gzipServer:
BWS/1.1Set-Cookie: delPer=0; path=/; domain=.baidu.com

空白行:同上,响应报文也用空白行来分隔header和数据响应体:响应的data

HTTP状态码:

HTTP与HTTPS:

HTTP存在一些问题:

信息为明文传输,存在被窃听的风险

接收方对消息没有校验,存在被篡改的风险

客户端对服务器身份无法确认

所以为了解决HTTP这些缺陷,在HTTP协议上加上了SSL/TLS协议,来保证HTTP协议的安全性。

具体流程:

采用非对称算法实现对对称密钥的加密,对称密钥对数据进行加密

使用摘要算法对数据进行校验

使用签名证书保证双方身份真实性

HTPP无状态

HTTP无状态协议,是指协议对于事务处理没有记忆能力,缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

Cookie

cookie 的传递会经过下边这 4 步:

  1. Client 发送 HTTP 请求给 Server
  2. Server 响应,并附带 Set-Cookie 的头部信息
  3. Client 保存 Cookie,之后请求 Server 会附带 Cookie 的头部信息
  4. Server 从 Cookie 知道 Client 是谁了,返回相应的响应

Cookie 中文翻译是甜品,使用 Cookie 可以自动填写用户名、密码等,是给用户的一点甜头。

Server 拿到 Cookie 后面,通过什么信息才能判断是哪个 Client 呢?服务器的 SessionID。

Session

如果把用户名、密码等重要隐私都存到客户端的 Cookie 中,还是有泄密风险。为了更安全,把机密信息保存到服务器上,这就是 Session。Session 是服务器上维护的客户档案,可以理解为服务器端数据库中有一张 user 表,里面存放了客户端的用户信息。SessionID 就是这张表的主键 ID。

Session 信息存到服务器,必然占用内存。用户多了以后,开销必然增大。为了提高效率,需要做分布式,做负载均衡。因为认证的信息保存在内存中,用户访问哪台服务器,下次还得访问相同这台服务器才能拿到授权信息,这就限制了负载均衡的能力。而且 SeesionID 存在 Cookie,还是有暴露的风险,比如 CSRF(Cross-Site Request Forgery,跨站请求伪造)。

如何解决这些问题呢?基于 Token 令牌鉴权。

Token

这种方式跟session的方式流程差不多,不同的地方在于保存的是一个token值到redis,token一般是一串随机的字符(比如UUID),value一般是用户ID,并且设置一个过期时间。每次请求服务的时候带上token在请求头,后端接收到token则根据token查一下redis是否存在,如果存在则表示用户已认证,如果token不存在则跳到登录界面让用户重新登录,登录成功后返回一个token值给客户端

优点是多台服务器都是使用redis来存取token,不存在不共享的问题,所以容易扩展。缺点是每次请求都需要查一下redis,会造成redis的压力,还有增加了请求的耗时,每个已登录的用户都要保存一个token在redis,也会消耗redis的存储空间。

Token 虽然很好的解决了 Session 的问题,但仍然不够完美。服务器在认证 Token 的时候,仍然需要去数据库查询认证信息做校验。为了不查库,直接认证,JWT 出现了。

JWT

JWT(全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

上面说法比较文绉绉,简单点说就是一种认证机制,让后台知道该请求是来自于受信的客户端。

首先我们先看一个流程图:

流程描述一下:

  1. 用户使用账号、密码登录应用,登录的请求发送到Authentication Server。
  2. Authentication Server进行用户验证,然后创建JWT字符串返回给客户端。
  3. 客户端请求接口时,在请求头带上JWT。
  4. Application Server验证JWT合法性,如果合法则继续调用应用接口返回结果。

可以看出与token方式有一些不同的地方,就是不需要依赖redis,用户信息存储在客户端。所以关键在于生成JWT,和解析JWT这两个地方

posted @ 2022-05-11 15:17  cwstd  阅读(37)  评论(0编辑  收藏  举报