25

我有一个 REST 端点接受 POST 请求以将代码标记为已兑换。该代码只能在特定日期之间兑换。

如果有人试图提前兑换代码,我应该如何应对?

我怀疑 HTTP 403,禁止,是正确的选择,但是 w3c 声明“不应该重复请求”,而在这种情况下,我预计请求会在以后重复。

4

4 回答 4

23

409 冲突

由于与资源的当前状态冲突,无法完成请求。仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许使用此代码。响应正文应该包含足够的信息让用户识别冲突的来源。理想情况下,响应实体将包含足够的信息供用户或用户代理解决问题;但是,这可能是不可能的,也不是必需的。

如果他们试图兑换已经兑换的优惠券,403 Forbidden更有意义,尽管410 Gone在这种情况下也很优雅。

404 Not Found并不理想,因为资源确实存在,但是如果您不想指定 403 的原因,或者出于安全原因想要隐藏资源的存在,则可以使用它。

如果您使用的是HATEOAS,那么您还可以在可以兑换优惠券时仅redeem在优惠券资源中包含超媒体控件(通过 a 检索)来阻止您的客户(可以这么说);GET尽管这不会阻止过度绑定的客户尝试赎回它。

于 2012-06-19T02:21:16.180 回答
1

编辑:感谢一些好的批评(见下文),我想警告这个答案。它基于 Richardson & Ruby 的文章,可以说与403 Forbidden 上的 httpbis 文章不太吻合。(就个人而言,现在我正在向 409 学习,正如汤姆在单独的答案中所解释的那样。)

403 Forbidden是最好的选择。我将逐行引用Richardson 和 Ruby 的 RESTful Web Services 。如您所见,403 非常适合:

客户端的请求格式正确,但服务器不想执行它。

查看!

这不仅仅是凭据不足的情况:那将是 401(“未经授权”)。这更像是一种只能在特定时间或从特定 IP 地址访问的资源。

查看!

403 的响应意味着客户端请求了一个确实存在的资源。与 401(“未授权”)一样,如果服务器甚至不想提供此信息,它可以撒谎并发送 404(“未找到”)。

您在上面写道:“代码表示可以在它上线之前被 GETted。” 所以,你并没有试图隐藏任何东西。所以,坚持使用 403。检查!

如果客户端的请求格式正确,为什么这个状态码是4xx系列(客户端错误)而不是5xx系列(服务器端错误)?因为服务是根据请求的某些方面而不是其形式做出决定的;比如说,提出请求的时间。

查看!客户的请求已更正,但不适用于特定时间。

我们四对四。403 代码是赢家。也没有其他代码匹配。

所有这一切都表明,一个普通的、非特定的 400 不会是错误的,但不会那么具体或有用。

另一个答案建议使用 409 冲突代码。虽然值得考虑,但它并不适合。这就是为什么。根据 Richardson & Ruby 的说法:

获得此 [409] 响应意味着您试图将服务器的资源置于不可能或不一致的状态。当您尝试删除非空存储桶时,Amazon S3 会提供此响应代码。

在“活动”之前声明促销不会“将服务器资源置于不一致的状态”。它会破坏一些商业规则——并导致作弊——但它不会引起我所看到的逻辑矛盾。

因此,无论您在提出问题时是否意识到这一点,403 都是一个不错的选择。:)

于 2012-06-19T03:55:11.450 回答
1

由于 Rest URL 应该代表资源,我会回复404 - Not Found
该资源仅在某些日期之间可用,因此在任何其他日期都找不到。

于 2012-06-18T09:39:40.307 回答
-1

当它说请求“不应该重复”时,它指的是您应该发送给查看者的消息。

它与是否重复实际请求无关。(如果他/她愿意,用户将一遍又一遍地收到相同的 403 消息。)

也就是说,404 不适用于此,因为资源可用 - 只是代码不可兑换/禁止兑换。它实际上是有害的,因为它告诉用户您可能在 URL 链接或服务器配置中犯了错误。

当然,这假设您在适当的日期返回 200。

于 2012-06-18T09:58:12.763 回答