什么是一个适当的HTTP状态码由REST API服务返回验证失败?

我目前返回401未经授权,每当我在我的Django/活塞基于REST API应用程序遇到验证失败。 已经看了HTTP状态码注册表 我不相信这是一个合适的代码验证失败,你们都建议什么?< / p >

  • 400错误请求
  • 401年未经授权
  • 403年被禁止的
  • 405方法不允许
  • 406不可接受
  • 412前置条件失败
  • 417期望失败
  • 422不可处理实体
  • 424依赖失败

更新:上面的“验证失败”是指应用程序级别的数据验证失败,即错误指定的日期时间,伪造的电子邮件地址等。

277312 次浏览

RFC 2616中有更多关于这些错误语义的信息,它记录了HTTP 1.1。

就我个人而言,我可能会使用400 Bad Request,但这只是我个人的观点,没有任何事实支持。

你说的“验证失败”到底是什么意思?你在验证什么?你指的是语法错误(比如格式错误的XML)吗?

如果是这样的话,我认为400个坏请求可能是正确的,但如果不知道你正在“验证”的是什么,就不可能说出来。

我想说,从技术上讲,这可能不是HTTP故障,因为资源(假设)是有效指定的,用户是经过身份验证的,并且没有操作故障(然而,即使规范也包括一些保留代码,如402 Payment Required,严格来说也不是与HTTP相关的,尽管在协议级别上可能是可取的,这样任何设备都可以识别这种情况)。

如果确实是这样,我将在响应中添加一个带有应用程序错误的状态字段,例如

<status><code>4</code><message>日期范围为invalid</message><

如果“验证失败”;意味着在请求中有一些客户端错误,然后使用HTTP 400(坏请求)。例如,如果URI应该具有ISO-8601日期,而您发现它的格式错误或指向2月31日,那么您将返回HTTP 400。同样,如果您希望实体主体中有格式良好的XML,但它无法解析。

(1/2016):在过去的五年里,WebDAV的更具体的HTTP 422(不可处理实体)已经成为HTTP 400的一个非常合理的替代方案。参见它在JSON API中的使用实例。但是请注意,HTTP 422已经将变成了HTTP 1.1, rfc - 7231

Richardson和Ruby的rest式Web服务包含了一个关于何时使用各种HTTP响应代码的非常有用的附录。他们说:

< p > 400(“错误请求”)
重要性:高。
这是一般的客户端错误状态,当没有其他合适的4xx错误代码时使用。它通常用于客户端提交一个表示和 PUT或POST请求,并且表示形式是正确的格式,但是它没有使 任何有意义的。(381页)< / p >

和:

< p > 401(“未经授权的”)
重要性:高。
客户端试图操作受保护的资源,但没有提供适当的身份验证凭据。它可能提供了错误的凭证,或者根本没有提供。 凭证可以是用户名和密码、API密钥或身份验证 令牌——不管服务期望什么。这对客户来说是很常见的 一个URI请求,并接受401,这样它就知道要发送什么样的凭据 以及什么样的格式。[…]< / p >

来自RFC 4918(也在http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml中有记录):

422(不可处理实体)状态码表示服务器 理解请求实体的内容类型(因此是 415(不支持的媒体类型)状态码不合适) 请求实体的语法是正确的(因此是400(坏请求) 状态码不合适),但无法处理包含的 指令。例如,如果XML 请求主体包含格式良好的(即语法正确),但是 语义错误,XML指令

数据库中的副本应该是409 CONFLICT

我建议使用422 UNPROCESSABLE ENTITY来处理验证错误。

我在这里对4xx代码作了更详细的解释:http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/

下面就是:

rfc2616#section-10.4.1 - 400错误请求

服务器无法理解请求,原因是格式不正确 语法> < /强。

.客户端不应该重复没有修改的请求

Rfc7231 #章节-6.5.1 -6.5.1。400错误请求

400 (Bad Request)状态码表示服务器不能访问 或者由于感知到某些东西而不处理请求 < em >(如。,格式错误的请求语法,无效的请求消息帧,或欺骗性的请求路由).

. {/p> .

是指畸形(不完善)的情况!

Rfc4918 - 11.2。422不可处理实体

422(不可处理实体)状态码表示服务器
理解请求实体的内容类型(因此415(不支持的媒体类型)状态码是不合适的),请求实体的语法正确(因此400(坏请求)状态码是不合适的),但无法处理包含的指令。例如,如果XML请求体包含格式良好(即语法正确),但语义错误, XML指令,则可能发生此错误条件

结论

经验法则:[_]00涵盖了最常见的情况和指定代码未涵盖的情况。

422适合最佳对象验证错误(正是我的建议:)
对于语义错误,考虑类似于“此用户名已经存在”的验证。< / p >

400被错误地用于对象验证

如果你正在验证数据,而数据不是,根据定义的规则,最好发送422(不可处理实体),这样发送方就会明白他违反了约定的规则。

坏请求是语法错误。有些工具,如postman,会提前显示语法错误。

下面是要讨论的另一个有趣场景。

如果它是一个类型检测API,例如接受某个本地存储的parquet文件的引用作为输入,并且在读取组成文件的块的一些元数据后,可能会意识到一个或多个块大小超过了配置的阈值,因此服务器认为文件没有正确分区并拒绝启动类型检测过程。 这种验证是为了防止两种(或两种)情况中的一种:(1)处理时间长,用户体验差;(2)服务器应用程序爆炸OutOfMemoryError

在这种情况下,什么才是适当的回应?

400 (Bad Request)吗?-大体上是这样的。

401 (Unauthorized i.e. Unauthenticated)吗?——无关。

403 (Forbidden i.e. Unauthorized)吗?-有些人会认为在这种情况下可能有点合适-

422 (Unprocessable entity)吗?-许多旧的答案提到这是输入验证失败的适当选项。在我的情况下使用它让我困扰的是这个响应代码的定义说它“由于语义错误”;但我不太明白语义错误在这种情况下意味着什么,以及我们是否可以将这次失败视为语义错误失败。

还有所谓简单的“输入”概念;作为“输入验证”的一部分;在这种情况下,客户端提供的物理输入只是一个指针,一个对存储在服务器中的某个实体的引用,其中实际的验证是对存储在服务器中的数据(parquet文件元数据)进行的,并结合客户端试图触发的操作(类型检测)。

413 (PayloadTooLarge)吗?通过不同的代码,我遇到了一个可能适合我的情况下,一个没有人在这里提到,这是413 PayloadTooLarge,我也想知道它是否适合或再次,因为它不是实际的有效载荷发送的请求太大,但资源的有效载荷存储在服务器中。

这让我想到,也许5xx的回复在这里更合适。

507 Insufficient Storage吗?如果我们说“储存”;就像“记忆”;如果我们还说我们在这里快速失败,声称我们没有足够的内存(或者我们可能会因为内存耗尽而崩溃)来处理这个工作,那么也许507是合适的。但事实并非如此。

我的结论是,在这种情况下,服务器由于时空相关的限制而拒绝调用对资源的操作,最合适的响应将是413 PayloadTooLarge