Http权威指南笔记(十)——认证

2023-05-16

现在大多数网站都会在cookie等客户端识别机制的基础上建立自己的认证机制。但是HTTP规范中提供的原生认证机制还是有必要了解下,了解这些后才能更好理解那些自己建立的认证机制。

HTTP原生认证功能一般分为基本认证摘要认证。基本认证相对简单,但是安全性相对较弱,摘要认证要复杂一些,当然安全性也会高一些。在介绍这两种认证方式之前,我们先看下HTTP中涉及到认证的一些通用概念。

1 HTTP认证机制

所谓认证就是出具一定的东西证明你的身份。HTTP中提供了一个**质询 / 响应(challenge/response)**框架来提供认证功能。

1.1 认证过程

当Web服务器收到一条HTTP请求时,如果该请求的资源是需要认证的,服务器就会返回一个”认证质询“的响应,客户端收到该响应后,会要求用户提供响应的认证资料(如用户名/密码等),随后客户端会携带上认证证书重新发起请求,服务器收到后会对该请求的证书进行验证,如果验证通过就返回正常所需响应,如果验证失败,可以返回一条错误信息或者再次返回一条”认证质询“的响应。整个过程如下图所示:
HTTP认证过程

1.2 认证有关的协议和首部

HTTP 通过一组可定制的控制首部,为不同的认证协议提供了一个可扩展框架。总体来说根据上述的认证步骤可以将首部概括为下表的内容:

步骤首 部描 述方法/状态
请求第一条请求没有认证信息GET
质询WWW-Authenticate服务器用 401 状态拒绝了请求,说明需要用户提供用户名和密码。服务器上可能会分为不同的区域,每个区域都有自己的密码,所以服务器会在 WWW-Authenticate 首部对保护区域进行描述。同样,认证算法也是在 WWW-Authenticate 首部中指定的401 Unauthorized
授权Authorization客户端重新发出请求,但这一次会附加一个 Authorization 首部,用来说明认证算法、用户名和密码GET
成功Authentication-Info如果授权证书是正确的,服务器就会将文档返回。有些授权算法会在可选的 Authentication-Info 首部返回一些与授权会话相关的附加信息200 OK

将上述的步骤和首部结合起来,描述认证过程如下图所示:
HTTP认证步骤
当然,上面的步骤只是一个概括性描述,实际使用过程中,根据使用的认证协议不同,中间可能会有一些不同。后面会具体介绍HTTP官方提供的两种认证协议(基本认证和摘要认证)。

1.3 安全域

所谓的安全域就是,将一组资料统组织管理起来,形成一个访问权限控制。这个访问权限控制点所有资料组合起来就是一个安全域。有些时候我们需要将不同的资源组织成不同的安全域进行不同的访问权限控制,比如对于一个公司普通职员来说,财务数据属于一个公司保密资料,只有特定认证后的员工才能访问,所以需要建立一个安全域。对于员工的的个人家庭文档,属于个人隐私,这个时候又会建立一个安全域。
在HTTP中,在WWW-Authenticate中提供了一个realm指令,用于指定安全域。在上面1.2小节的示例中,我们的WWW-Authenticate就包含一个”Family“的安全域。起始本质就是提供一个字符串作为一个安全域的标识。

介绍完HTTP中的一些认证基本知识,下面我们分别对基本认证和摘要认证进行一些简单的阐述介绍。

2 基本认证

2.1 基本认证过程

在基本认证中,Web服务器如果需要提出质询,可以通过返回一个401状态码,并用 WWW-Authenticate 响应首部指定要访问的安全域,客户端在收到该响应后,就会要求用户提供用户名/密码,然后将这些信息进行一些处理后,用Authorization发送给服务器。具体认证过程参考前面的1.2小节即可,那一小节的举例就是基本认证的步骤。
基本认证过程中的首部信息如下表所示:

质询/响应首部语法及描述
质询(服务器发往客户端)网站的不同部分可能有不同的密码。域就是一个引用字符串,用来命名所请求的文档集,这样用户就知道该使用哪个密码了:
WWW-Authenticate: Basic realm=quoted-realm
响应(客户端发往服务器)用冒号(:)将用户名和密码连接起来,然后转换成 Base-64 编码,这样在用户名和密码中包含国际字符会稍微容易一些,也能尽量避免通过观察网络流量并只进行一些粗略的检查就可以获取用户名和密码情况的发生:
Authorization: Basic base64-username-and-password

可以看到,基本认证过程中是没有使用到Authorization-Info首部的。

2.2 基本认证的加密算法

HTTP 基本认证将(由冒号分隔的)用户名和密码打包在一起,并用 Base-64 编码方式对其进行编码。Base-64编码简单说就是将8个字节序列划分为6个字节的块,每个块会在一个特殊的由64个字符组成的字母表中选择一个字符。详细的信息感兴趣的朋友可以自己搜索下。

2.3 代理认证

代理作为服务器角色的时候,也是可以要求对客户端进行认证的,比如一些公司或者组织会统一使用一个认证代理,集中管理员工对公司资源的访问策略。代理认证和服务器认证的过程基本一致,只是首部稍微有些差别,如下表所示:

Web服务器代理服务器
Unauthorized status code: 401Unauthorized status code: 407
WWW-AuthenticateProxy-Authenticate
AuthorizationProxy-Authorization
Authentication-InfoProxy-Authentication-Info

2.4 基本认证的问题

基本认证虽然实现简单,但是其在安全性上非常薄弱,存在以下几个安全问题:

  1. 基本认证会直接发送用户名和密码,虽然用户名和密码是经过Base-64编码的,但是这种编码是可逆的,而且非常容易反向编码获取真正的用户名和密码。相当于是一种“明文”传输了。
  2. 针对第一个问题,如果是专用的客户端和服务器,协商好之后,可以在编码之前就对用户名和密码进行加密处理,即便是这样处理后,也可以拦截到加密后的用户名和密码,进行重放攻击。
  3. 基本认证中客户端对服务器没有进行验证,恶意第三方很容易冒充服务器接收客户端发送的用户名和密码。

所以我们如果只是单纯是用基本认证,没有配合其他安全措施(如SSL)使用的话,安全性是非常弱的。所以这种一般适用于一些对安全性要求不太高的情形,如:公司对内部员工的管理上。

3 摘要认证

上面介绍了基本认证,可以看到基本认证的安全性很低,所以HTTP提供了另外一种安全性更高,当然实现也相对复杂一些的摘要认证方式。
相对于基本认证,摘要认证的安全性提升主要有一下几个方面:

  • 不会发送明文用户名和密码
  • 防止恶意的重放认证攻击
  • 可以有选择的防止对报文内容的修改

3.1 摘要认证改进的地方

3.1.1 对于密码的保护

上面提到,摘要认证不会明文发送密码。因为摘要认证是通过对数据(这里简单看成密码)进行不可逆的加密方式(常见的是MD5)后进行传输的。即使拦截到传输的内容,也没法逆转获得密码。服务收到认证请求后,也只能是通过对密码进行同样方式加密和对比加密后的摘要,而不是直接对比密码,看是否一致。

3.1.2 防止重放攻击

如果只是对认证信息进行不可逆的加密处理,攻击者在拦截到摘要信息后,同样可以发动重放攻击,所以我们还需要一个手段来防止这样的事情。在摘要认证中,服务器可以发送一个随机数给客户端,客户端在计算摘要的时候,需要加上该随机数。由于该随机数会经常变化,所以加密后的摘要也会经常变化。这样就可以攻击者拦截到摘要发起重复攻击了。

3.1.3 摘要认证的握手机制

摘要认证和基本认证的流程大体上一致。但是摘要认证还添加了一些新的选项,具体握手机制如下图所示:
摘要认证握手机制
从上面可以看到,这里客户端也可以选择对服务器质询,所以相对于基本认证,不容易受到一些冒充服务器骗取信息。
这里我们将基本认证和摘要认证的过程进行对比如下:
基本认证和摘要认证对比

3.2 摘要的计算

摘要认证的核心就是通过一些计算,得出摘要的过程。得出摘要的安全性越高,那么摘要认证的安全性也就越高。所以这里我们简单介绍下摘要认证的计算过程。

3.2.1 摘要计算的数据来源

上面我们基本认证加密的时候,数据就是用户名+冒号(:)+密码。摘要认证的数据来源就要相对复杂一些了。摘要认证中的数据总的分为两个部分:

  • A1——一个包含安全信息(用户名、密码、保护域和随机数等)的数据块
    这里的A1根据提供的算法不同,数据组成也不太相同,目前RFC2617定义了两种算法(MD5和MD5-sess),A1对应的数据分别如下:
算法A1的值
MD5A1 = <user>:<realm>:<password>
MD5-sessA1 = MD5(<user>:<realm>:<password>):<nonce>:<cnonce>

这里的nonce和cnonce分别代表服务器随机数和客户端随机数

  • A2——一个包含报文中非保密属性的数据块(比如 URL、请求方法和报文实体的主体部分等)
    这个数据一般只和报文自身信息相关,同样根据RFC2617定义的不同保护质量(qop),A2包含的数据也不相同,具体如下表所示:
qopA2
未定义<request-method>:<uri-directive-value>
auth<request-method>:<uri-directive-value>
auth-int<request-method>:<uri-directive-value>:H(<request-entitybody>)

可以看到默认的是采用auth的方式,除非指定qop="auth-int"。这里的H(<request-entitybody>)代表一种算法,下面会详细介绍。

3.2.2 摘要计算函数

摘要计算过程中,涉及到两个函数,这里我们命名如下:
H ( d ) H(d) H(d)——这个函数就代表一个加密函数,一般指MD5,所以等价于 M D 5 ( d ) MD5(d) MD5(d)。这里的d就代表待加密的数据。
K D ( s , d ) KD(s,d) KD(s,d)——这个就是最终使用的摘要计算函数。一般也是使用MD5的方式,只是这里的输入数据s和d分别代表上面提到的保密数据和非保密数据连个部分,一般使用冒号(:)将两部分进行连接。所以最终这两个公司可以变形为如下:
H ( d ) = M D ( d ) H(d) = MD(d) H(d)=MD(d)
K D ( s , d ) = H ( c o n c a t e n a t e ( &lt; s e c r e t &gt; : &lt; d a t a &gt; ) ) KD(s,d) = H(concatenate(&lt;secret&gt;:&lt;data&gt;)) KD(s,d)=H(concatenate(<secret>:<data>))

3.2.3 摘要算法总结

根据上面两个小节的内容,根据RFC2617的定义,这里将算法汇总如下:

qop摘要算法备 注
未定义KD(H(A1), <nonce>:H(A2))不推荐
auth 或 auth-intKD(H(A1), <nonce>:<nc>:<cnonce>:<qop>:H(A2))推荐

总结起来就是,在未定义qop的情况下,为了和RFC2069兼容,使用保密信息加上随机数的方式,如果定了qop为auth或者auth-int,除了保密信息和服务器随机数,还需要加上随机数计数(nc),客户端随机数(conce)和qop。这里如果我们将H和KD函数替换为我们常用的MD5加密方式,就可以得到如下算法:

qop算  法展开的算法
未定义<undefined>
MD5
MD5-sess
MD5(MD5(A1):<nonce>:MD5(A2))
auth<undefined>
MD5
MD5-sess
MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
auth-int<undefined>
MD5
MD5-sess
MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))

从上面的表格可以看到,算法总结起来无外乎就是
M D 5 ( M D 5 ( A 1 ) : &lt; n o n c e &gt; : M D 5 ( A 2 ) ) MD5(MD5(A1):&lt;nonce&gt;:MD5(A2)) MD5(MD5(A1):<nonce>:MD5(A2))

M D 5 ( M D 5 ( A 1 ) : &lt; n o n c e &gt; : &lt; n c &gt; : &lt; c n o n c e &gt; : &lt; q o p &gt; : M D 5 ( A 2 ) ) MD5(MD5(A1):&lt;nonce&gt;:&lt;nc&gt;:&lt;cnonce&gt;:&lt;qop&gt;:MD5(A2)) MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
只是根据算法和qop的不同,会影响到A1和A2两个数据块的组成而已。

3.2.4 随机数的选择

摘要认证的安全和随机数的选择有很大关系,随机数选择就显得比较重要。RFC2617中建议随机数采用如下方式生成:
BASE64(time-stamp H(time-stamp “:” Etag “:” private-key))
这里的time-stamp是服务器产生的时间戳。Etag是与请求资源相关的HTTP报文中Etag首部的值,private-key就是一个服务器自己知道的一个值。
通过这种方式计算出来的随机数,time-stamp可以控制我们随机数的有效期,加上Etag可以可以在资源更新后要求重新认证,防止重放攻击。
实际开发中,通常一般GET请求会是使用一个时间戳来控制有效期,而如POST或者PUT之类的请求,一般是使用一次性随机数,防止重复提交。

3.2.5 对称认证

所谓对称认证,就是客户端也可以对服务器进行质询认证。同样是通过客户端提供随机值来实现的。服务器可以根据这个随机值和共享的保密信息来生成摘要,然后放在响应的Authoriztion-Info首部中返回给客户端。
不过这个和请求认证摘要的计算方法稍微有点不同,因为响应中没有方法,所以相对于请求摘要A2数据区会缺少方法这一部分的数据,对比如下表所示:

qopA2数据
请求响应
未定义<request-method>:<uri-directive-value>:<uri-directive-value>
auth<request-method>:<uri-directive-value> :<uri-directive-value>
auth-int <request-method>:<uri-directive-value>:H(<request-entity-body>) :<uri-directive-value>:H(<response-entity-body>)

3.3 摘要认证会话和预授权

客户端响应对保护空间的 WWW-Authenticate 质询时,会启动一个此保护空间的认证会话(与受访问服务器的标准根结合在一起的域就定义了一个“保护空间”)。这个认证会话会一直持续到客户端收到了另一“保护空间”的质询,所以客户端在此期间应该记住一些与认证有关的值(如:用户名、密码、随机数、随机计数等),方便随时构建Authorization首部。
由于随机数是有时效性的,所以可能某个时候随机数就失效了,这个时候服务器收到随机数过时的认证请求后,应该返回一个携带新的随机数的状态码为401的响应,同时在响应中指定stale=true,用于告知客户端,随机数过期了,可以使用之前的用户名和密码等信息,加上新的随机数来重新认证即可。

如果我们对这种请求/质询的对话不进行优化,那么意味着每次我们发起请求都会走一遍请求/质询的流程。如果我们客户端除了第一次请求/质询后,后面每次发起请求的时候能够预先算出摘要,发起请求的时候直接将摘要放入Authorization首部,那么就不用每次都走一遍请求/质询的流程,这样会节约资源也会增加效率,这里所说的预先算出正确的摘要,就是预授权。下图展示了预授权处理后和普通请求/质询之间的流程差异:
预授权
通过前面的介绍,客户端计算摘要,如果我们第一次请求/质询后将用户名、密码等信息保存下来后,剩下的就是缺少服务器提供的随机值,如果我们能够预先知道随机值,那么就能正确的计算摘要了。一般有下面三种方式,可以让服务器预先将随机值给到客户端。

  1. 预先生成一个随机数
    可以在 Authentication-Info 成功首部中将下一个随机数预先提供给客户端。这个首部是与前一次成功认证的 200 OK 响应一同发送的。如下:
    Authentication-Info: nextnonce="<nonce-value>"
    虽然这样可以让客户端预先计算摘要的目的,但是这个方法也有个就是不支持管道的特性。这种处理,意味着必须在上一个请求发起后,并收到响应(整个事务流程完成)后才能发起下一个请求,就不能利用管道连续发出多个请求了。
  2. 受限随机值重用机制
    这种不是预先生成随机值并返回给客户端,而是将一个随机值设置一个可重用的次数或者时间。那么在这个有效期内,客户端就可以直接计算出摘要,同时这个方法还不破坏管道的特性。当这个随机值失效后,返回一个401错误并携带stale=true和新随机值的信息即可。但是也有个缺点,因为随机值是可以重用的,所以可能有受到重放攻击的风险。所以这个时候需要寻找到一个相对平衡的有效性限制。
  3. 同步生成随机数
    这种方式,就是服务器和客户端共享一些信息,然后用同一套机制生成随机数,那么客户端就可以随时自己生成随机数来进行摘要计算。但是这种方式对随机数的生成方式要做好保护措施,如果被第三方预测或者获取到,那就危险了。

3.4 增强保护质量

可以在三种摘要首部中提供 qop 字段:WWW-Authenticate、Authorization 和 Authentication-Info。该字段就是用于协商保护质量的。
服务器首先在 WWW-Authenticate 首部输出由逗号分隔的 qop 选项列表。然后客户端从中选择一个它支持且满足其需求的选项,并将其放在 Authorization 的 qop 字段中回送给服务器。
为了兼容RFC2029,所以qop被设定为一个可选字段。但是为了安全性着想,应该尽量满足提供qop支持并使用qop。
在RFC2617中提供了两种qop的可选值:也就是我们前进已经介绍了的auth和auth-int,两者的区别是auth-int带有报文完整性保护支持,因为使用auth-int的时候,使用H(d)算法的实时,会对报文实体而不是对报文信息继续散列计算。

3.5 摘要认证首部

其实我们的摘要认证首部在介绍前面内容的时候,都介绍的差不多了,这里我们结合前面的基本认证做一个汇总表格,如下:

阶段基  本摘  要
质询WWW-Authenticate: Basic realm="<realm-value>"WWW-Authenticate: Digest
realm="<realm-value>“
nonce=”<nonce-value>"
[domain="<list-of-URIs>"]
[opaque="<opaque-token-value>"]
[stale=<true-or-false>]
[algorithm=<digest-algorithm>]
[qop="<list-of-qop-values>"]
[<extension-directive>]
响应Authorization: Basic <base64(user:pass)>Authorization: Digest
username="<username>“
realm=”<realm-value>“
nonce=”<nonce-value>"
uri=<request-uri>
response="<32-hex-digit-digest>"
[algorithm=<digest-algorithm>]
[opaque="<opaque-token-value>"]
[cnonce="<nonce-value>"]
[qop=<qop-value>]
[nc=<8-hex-digit-nonce-count>]
[<extension-directive>]
Infon/aAuthentication-Info:
nextnonce="<nonce-value>">
[qop="<list-of-qop-values>"]
[rspauth="<hex-digest>"]
[cnonce="<nonce-value>"]
[nc=<8-hex-digit-nonce-count>]

这里只是简单的介绍了首部,起始摘要相关的首部是非常复杂的,感兴趣的朋友可以自己去找找资料看看。

这里摘要认证和基本认证一样,我们不能简单实现了认证就完事,还需要考虑一些其他问题:

  • 多重质询:服务器可以提供一个可供客户端选择的质询列表,客户端选择自己支持一种方式
  • 差错处理:如果指令不对或者不当,服务器就应该返回400 Bad Request响应,同时记录下该次请求,如果发现有多次相同错误,有可能是攻击现象
  • 重写URI:代理可以重写URI,如对主机名标准化、转义一些字符等,这样URI被修改后,可能造成认证失败
  • Cache:同基本认证一样,对于有Authorization首部的响应,我们缓存的时候,应当谨慎处理。

到这里,我们认证的内容就介绍完了,认证是一个非常复杂的东西,本篇也仅仅就是简单介绍了一些基本的东西,真正感兴趣或者想要掌握的朋友,还是建议去看一些专门介绍的资料。特别是对于安全性这一块的内容,更加要注意,不管是基本认证和摘要认证,安全性和SSL比起来(后面会有文章来介绍HTTPS),都显得很薄弱,要特别注意处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Http权威指南笔记(十)——认证 的相关文章

  • REST DELETE 真的是幂等的吗?

    DELETE 应该是幂等的 如果我删除http example com account 123 http example com account 123它将删除该帐户 如果我再次这样做 我会收到 404 错误吗 因为该帐户已不存在 如果我尝
  • 如何从一个端口为 Jetty 提供 https 和 http 服务?

    我知道这是一个重复的问题 但原始发帖者提出这个问题的原因是错误的 我并不是暗示我问它是为了right原因 但让我们看看 我们有一个在非标准端口号上运行的 Web 服务 尽管用户似乎能够记住端口号 但有时他们会错误地输入 http 而不是 h
  • 如何为 HTTP GET 的多个 Key-Value 参数设计 REST URI

    我正在设计一个 RESTful API 一项服务应该提供多个键值对的查询功能 例如 客户端可以使用一个 HTTP GET 请求来查询不同的产品及其关联的数量 客户想要查询金额为 44 的产品 1 和金额为 55 的产品 2 我实际上不希望我
  • 即使禁用缓存,Safari 也会缓存 GET 请求

    我已经将我所知道的所有标头设置为在我的服务器上禁用缓存 甚至禁用 ETAG 但 Safari 仍然偶尔 大约 50 次 缓存我的请求 Workflow 我正在实施 oauth 1 所以 浏览器使GET api user request 服务
  • 无法更改 php 会话 cookie 名称

    我将现有且成功运行的站点复制到新的开发服务器 新服务器上的登录现在已损坏 我追踪到虽然会话 cookie 已重命名 ini set session name DOMAIN1 浏览器继续将会话 cookie 存储为 PHPSESSID 当我从
  • C# HttpWebRequest 服务器未返回完整响应

    我正在向返回带有数据的 HTML 的服务器发出 HTTP 请求 但有时它会 停在中间 没有任何明确的解释 例如响应结束 Content length 14336 chars p p br ul ul example com var auth
  • 我应该如何处理 Android 应用程序中 http post 的服务器超时和错误代码响应?

    我的 Android 应用程序会向 URL 发送 http 帖子 例如http example com 电子邮件受保护 http example com abc php email abc xyz com因此 Android 应用程序基本上
  • HTTP PUT 请求通常如何发出?

    我知道 HTTP PUT 是一个幂等请求 根据定义 引用自rfc http www w3 org Protocols rfc2616 rfc2616 sec9 html The PUT method requests that the en
  • 使用创建的 201 进行重定向

    有没有办法通过 201 答案重定向 RFC规定新创建的资源必须在Location标题 我确实指定了它 我假设浏览器会重定向 但事实并非如此 即使页面没有内容 我希望用户在 POST 操作之后重定向到新资源 因此我很想使用303 See Ot
  • 使用PHP获取http url参数而不自动解码

    我有一个像这样的网址 test php x hello world y 00h 00e 00l 00l 00o 当我将它写入文件时 file put contents x txt GET x gt hello world file put
  • 摆脱浏览器控制台中的 401(未经授权)ajax 错误

    我正在使用 javascript 通过 api 调用jQuery ajax http api jquery com jQuery ajax 称呼 如果用户未经过身份验证 API 会响应 401 并且我只想针对此调用忽略此错误 我已经尝试了
  • 构建可扩展 Web 应用程序的书籍? (数据库性能/调优、网络、一般性能等)[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 从计算机科学专业毕业并作为一名从事 Web 应用程序的软件工程师进入 现实世界 后 我对如何正确扩展 W
  • 把自己限制在HTTP1.0有什么用吗?

    我负责构建一些工具来帮助最终用户测试为什么他们的浏览器可能无法与网站配合使用 我被告知它可能不起作用的原因之一是 需要 HTTP1 1 这一行 我浏览了大多数浏览器选项 只浏览了 IE 版本 6 及更高版本 even 9 允许您禁用 HTT
  • 尝试将过滤器添加到 Grizzly+Jersey 应用程序时出现问题

    我有这个服务器初始化类 package magic app main import org glassfish grizzly http server HttpServer import org glassfish jersey grizz
  • 通过 HTTPS 包含 Twitter Widgets.js

    当我们包含以下内容时 我在我们网站上的 HTTPS 服务页面上的混合内容方面遇到了一个小问题http platform twitter com widgets js http platform twitter com widgets js
  • HTTP 查询字符串和 []

    PHP 使用 在查询参数名称中 以确保多次出现的参数都出现在 GET超全局变量 否则只出现最后一次出现的情况 还有其他软件可以做到这一点吗 但从RFC 3986 https www rfc editor org rfc rfc3986 以及
  • 如何让 NSURLRequest 获取 Twitter 请求令牌?

    我正在尝试使用以下代码从 Twitter 获取请求令牌 NSMutableURLRequest mURLRequest NSMutableURLRequest alloc initWithURL NSURL URLWithString ht
  • gRPC(HTTP/2) 比使用 HTTP/2 的 REST 更快吗?

    目标是引入一种性能更好的传输和应用层协议latency and 网络吞吐量 目前 该应用程序使用REST with HTTP 1 1并且我们遇到了很高的延迟 我需要解决这个延迟问题并且我愿意使用gRPC HTTP 2 or 休息 HTTP2
  • 为什么使用 HTTP 动词?

    因为动词的目标是像 server domain getallrecords 或 server domain delete1record 或类似的 URL 而getallrecords delete1record都是专门为特定目的而设计的 为
  • 如何测试“If-Modified-Since”HTTP 标头支持

    使用 PHP 如何准确测试远程网站supports If Modified Since HTTP 标头 据我所知 如果您获取的远程文件自标头请求中指定的日期以来已被修改 它应该返回 200 OK 状态 如果尚未修改 则应返回 304 Not

随机推荐

  • vlc命令行: 转码 流化 推流

    写在命令行之前的话 xff1a VLC不仅仅可以通过界面进行播放 xff0c 转码 xff0c 流化 xff0c 也可以通过命令行进行播放 xff0c 转码和流化 还可以利用里面的SDK进行二次开发 vlc命令行使用方法 xff1a 1 x
  • C++ 简单实现HTTP GET/POST 请求

    HTTP 超文本传输协议 是一种客户端与服务端的传输协议 xff0c 最早用于浏览器和服务器之间的通信 xff0c 后来因为其使用灵活 方便等特点 xff0c 广泛用于客户端与服务端的通信 文章将简单介绍HTTP协议 xff0c 同时以C
  • STM32单片机HAL库下串口接收不定长数据

    xff33 xff34 xff2d xff13 xff12 单片机 xff28 xff21 xff2c 库下串口接收不定长数据 xff28 xff21 xff2c 库下的串口接收不定长数据代码配置代码实现代码演示总结 xff28 xff21
  • C++将一个数据格式化为固定长度的字符串

    经常会遇到将数据解析为文本文件的现象 xff0c 通常因为数据长度的不同导致 xff0c 可视化效果不好 写一个输入数据获取固定长度字符串的函数 xff0c 来得到一个固定长度的数据 xff0c 让格式化看起来好看一些 include lt
  • Socket原理与编程基础

    一 Socket简介 Socket是进程通讯的一种方式 xff0c 即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换 几个定义 xff1a xff08 1 xff09 IP地址 xff1a 即依照TCP IP协议分
  • mac 安装brew

    起因是这样的 xff0c 我想在mac上安装htop 然后我了解到可以用brew安装htop 然后再执行命令 brew install htop 所以我就开始吭哧吭哧安装brew 过程xue wei 曲折了一些 先是看到一个文章 xff0c
  • 【项目学习】C++实现高并发服务器——代码学习(三)用户注册登录功能

    项目来源 xff1a WebServer 上一篇 xff1a 存储解析HTTP请求报文 xff0c 创建响应报文 本文介绍以下功能的代码实现 利用RAII机制实现了数据库连接池 xff0c 减少数据库连接建立与关闭的开销 xff0c 同时实
  • 用CSS3实现动画进度条

    CSS3的新特性为我们实现漂亮的进度条扫清了障碍 xff0c 我们可以完全不需要任何图片和简单的Javascript代码就可以构建 一 第一个例子 效果图 xff1a Demo地址 xff1a http namepk sinaapp com
  • tcpdump命令使用详解

    tcpdump命令使用详解 疯狂的小企鹅的博客 CSDN博客 tcpdump命令详解全网最详细的 tcpdump 使用指南 王一白 博客园Tcpdump抓包工具实战教程 xff0c 让你知道一个抓包走天下 xff01 哔哩哔哩 bilibi
  • Chrome浏览器Postman插件安装包及安装教程

    最近电脑装了新环境 xff0c 以前本地的postman安装包竟然找不到了 xff0c 网上费尽心力找了很多资源 xff0c 终于找到纯净的安装包 xff0c 绕开套路 xff0c 现将Postman安装包及安装教程分享给各位 xff0c
  • LayoutInflater的错误用法(Avoid passing null as the view root )

    今天在练习使用Fragment的时候 xff0c 注意到在使用LayoutInflater的时候有黄色报警 xff08 Avoid passing null as the view root needed to resolve layout
  • Android M(6.0)运行时权限申请及遇到的坑

    一 概述 在对动态权限申请进行详细说明时 xff0c 还是先大致介绍下6 0后 xff0c google对权限的一个归类和划分 在Android M之前 xff0c 再开发应用的时候 xff0c 程序员只需要在AndroidManifest
  • Android DataBinding介绍(一)——简介、数据及方法事件绑定

    简介 Data binding 是Google在2015年7月发布的Android Studio v1 3 0 版本上引入的 xff0c 在2016年4月Android Studio v2 0 0 上正式支持 引入之初 xff0c 不支持双
  • CoordinatorLayout的使用(一)——简单使用

    简介 CoordinatorLayout是Android support design推出的新布局 xff0c 主要用于作为视图根布局以及协调子控件的行为 xff08 根据用户的触摸行为产生一定的动画效果 xff09 主要是通过设置子Vie
  • BottomSheetDialog的使用及注意事项

    一 BottomSheetDialog简介 用途 xff1a 底部弹起的view或dialog 实现 xff1a 其关键也是CoordinatorLayout与Behavior 要求 xff1a 采用View的形式展示的话 xff0c 用于
  • mac设置mysql的环境变量

    1 终端输入 xff1a PATH 61 34 PATH 34 usr local mysql bin 这种每次重新进入终端都得写一次 xff0c 比较麻烦 xff1b 2 改变 zshrc文件 终端输入 xff1a vim zshrc 按
  • 关于解决自定义FloatingActionButton滑动行为(Behavior)只隐藏不出现的问题

    最近在使用FloatingActionButton的时候 xff0c 自定义了其Behavior xff0c 然后发现在SDK在25及以上的时候 xff0c 出现了只能隐藏不能重新出现的问题 xff08 24及以下没有出现此问题 xff09
  • NestedScrolling机制解析(二)——NestedScrollView源码

    上一篇文章我们介绍了NestedScrollingParent和NestedScrollingChild接口 xff0c 了解了两个接口里的方法和相互之间的调用关系 这篇我们以NestedScrollView类为例 xff0c 看先嵌套滚动
  • CoordinatorLayout的使用(四)——通过AppBarLayout源码分析联动机制

    一 整体交互逻辑 上一篇文章 xff0c 我们从CoordinatorLayout源码出发 xff0c 分析了一下Behavior几个重点方法的调用逻辑和流程 知道了整个交互的分发流程 但是具体是怎么让一个不是ScrollingView类型
  • Http权威指南笔记(十)——认证

    现在大多数网站都会在cookie等客户端识别机制的基础上建立自己的认证机制 但是HTTP规范中提供的原生认证机制还是有必要了解下 xff0c 了解这些后才能更好理解那些自己建立的认证机制 HTTP原生认证功能一般分为基本认证和摘要认证 基本