空 HTTP POST 请求或 GET 请求通过 HTTP API 生成随机值
Posted
技术标签:
【中文标题】空 HTTP POST 请求或 GET 请求通过 HTTP API 生成随机值【英文标题】:Empty HTTP POST request or GET request to generate a random value through an HTTP API 【发布时间】:2013-10-16 10:54:15 【问题描述】:在我的 HTTP API 中,其中一个端点应该返回一个随机生成的值,并且该值将与端点的经过身份验证的调用者相关联。目前,我有以下结构:
GET http://example.com/random-ticket HTTP/1.1
Authorization: Basic base64-encoded-basic-auth-value
Accept: application/json
Host: example.com
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
Date: Thu, 03 Oct 2013 07:25:56 GMT
Content-Length: 59
"user-ticket":"Pfa42634e-1a2e-4a7d-84b9-2d5c46a8dd81"
发出 GET 请求以检索随机值。但是,HTTP GET calls should be idempotent 和我的上述实现不遵守该规则。另一方面,我不确定是否可以发出带有空消息正文的 HTTP POST 请求。
HTTP书执行此类操作的正确方法是什么?
【问题讨论】:
【参考方案1】: 安全 => 调用是否会导致服务器上的状态更改。 幂等 => 多个调用是否会导致服务器上的相同更改。所以问题不在于返回的数据。相反,它是服务器状态:因此,如果您将此值存储在服务器上,这会导致状态发生变化,那么它不适合 GET。否则如果是返回的数据就好了。如果相隔 10 分钟调用 http://***.com,则会返回不同的数据。
让我们看另一个例子,一个返回当前时间的时钟服务。每次调用时,都会得到不同的值,但调用本身不会导致服务器上的状态发生变化,因为时钟状态是单独维护的。所以这里使用 GET 是一个不错的选择。
【讨论】:
创建资源!= 在服务器上存储价值 @FilipW 我没有说存储值。它正在改变状态。 谢谢大家。这个答案更具描述性,消除了我所有的困惑。 您说“如果您将此值存储在服务器上,那么它不适合 GET。”【参考方案2】:HTTP 中绝对没有禁止使用空正文的 POST。
此外,消息还带有一种表示形式,即正文+标头。在您的情况下,正文的长度为 0,这很好,并且标头可以识别用户。
在此处查看讨论 - http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0273.html
【讨论】:
对不起,我说 GET 是混淆了!但还有一个问题是这里没有提到的服务器状态,它是关键。 我认为 OP 很清楚他不应该在这里使用 GET,所以我试图解释为什么他不应该害怕使用 POST 来代替 我也没有。如果随机数是在内存中生成的,并且不是会改变副作用的现有资源的一部分,则 GET 是完全可以的。 我们不是在谈论创建一个与服务器状态无关的值。据我了解,生成的票证将与用户相关联,因此有效地创建了一个新资源(“用户票证”资源)。这就是为什么我不认为时钟服务是一个很好的类比。【参考方案3】:使用带有 GET 的随机生成器没有问题,因为没有存储服务器状态。以同样的方式,您可以拥有一个接受参数并在调用 GET 时添加它们的计算器。关于可缓存的问题是一个有趣的问题,但并不真正适用于随机生成器,因为资源本质上没有被缓存。这仍然不能改变它可以以安全/幂等方式设计的事实。
对于没有正文的 POST,甚至在查询字符串中使用参数,这都很好。 POST 的关键在于它“可能”导致服务器发生变化。也不能保证它会,但你不能假设它不会像 GET 那样。无论是否设置了任何内容,都不会改变可以更改的事实。例如想象一个虚构的资源“\counter\increment”。每次你 POST 到它都会导致 \counter 增加。我没有发送任何有效负载,但我导致服务器状态发生变化,因此它应该是 POST 或 PUT。
【讨论】:
【参考方案4】:在这种情况下,您应该使用POST
,因为通过设计,GET
调用可以被缓存。关于空的帖子正文,没有问题。类似的场景也在讨论:POST with empty body,其中一篇文章提到:
没有 content-length 和 body 的 POST 等同于 Content-Length: 0 并且没有任何内容的 POST,例如,当您上传一个空文件时,这完全可能发生。资源由 URL 确定,服务器必须知道如何处理正文,包括它是否为空。实际上我没有看到这里的问题:-/
威利
【讨论】:
“GET 调用可以被缓存”这是正确的,但取决于您想要实现的数据一致性,即服务器上数据更改的频率。因此,您也可能有不想允许缓存的 GET 请求。此外,想想也不能缓存的经过身份验证的数据。所以你的缓存参数不完全适合这里。 您可以返回适当的缓存头。以上是关于空 HTTP POST 请求或 GET 请求通过 HTTP API 生成随机值的主要内容,如果未能解决你的问题,请参考以下文章
如果请求和响应的 uri 相同,为啥 Microsoft Edge 在调用 POST/REDIRECT/GET 方法时发送空的 http-referer?