REST API 服务针对验证失败返回啥适当的 HTTP 状态代码?

Posted

技术标签:

【中文标题】REST API 服务针对验证失败返回啥适当的 HTTP 状态代码?【英文标题】:What's an appropriate HTTP status code to return by a REST API service for a validation failure?REST API 服务针对验证失败返回什么适当的 HTTP 状态代码? 【发布时间】:2010-12-29 22:02:18 【问题描述】:

每当我在基于 Django/Piston 的 REST API 应用程序中遇到验证失败时,我都会返回 401 Unauthorized。 看过HTTP Status Code Registry 我不相信这是验证失败的合适代码,你们有什么建议?

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

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

【问题讨论】:

查看这个答案:***.com/a/2657624/221612 Fwiw,Kenny 的链接建议使用代码 422,因为 Jim 的回答现在是 below。 #TheMoreYouKnow #SavingYouAClick 我觉得401更清晰。 【参考方案1】:

如果“验证失败”意味着请求中有一些客户端错误,则使用 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 的 RESTful Web Services 包含一个非常有用的附录,说明何时使用各种 HTTP 响应代码。他们说:

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

和:

401(“未经授权”) 重要性:高。 客户端尝试在未提供正确身份验证凭据的情况下对受保护资源进行操作。它可能提供了错误的凭据,或者根本没有提供。 凭证可以是用户名和密码、API 密钥或身份验证 令牌——无论有问题的服务期望什么。客户制作是很常见的 请求 URI 并接受 401,这样它就知道要发送什么样的凭据 以及采用什么格式。 [...]

【讨论】:

但如果 URI 格式无效,404 可能更合适。 正如@ReWrite 所说,我也认为 422 更适合验证错误。 我会说这是错误的。当请求在语法上有问题时使用 400 Bad Request。我想说 ReWrite 推荐 422 是正确的,它是关于请求的 content 的。 @Kenji 是的,401(“未经授权”):“它可能提供了错误的凭据...”表示错误的用户和/或密码。 @JimFerrans 400 错误是因为给出的语法不正确。 401 错误特别是如果我试图访问我需要登录才能访问的页面并且我根本没有登录。 422 错误是针对语法正确但服务器拒绝服务的地方。错误的用户名/密码是正确的语法(不是 400 错误),我没有尝试访问需要登录的页面,因为我正在访问登录页面本身(不是 401 错误)。 401 错误应该用于只有用户可以访问的设置页面之类的东西【参考方案2】:

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

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

【讨论】:

我会推荐 422 - Unprocessable Entity for validation failures over 400 - Bad Request【参考方案3】:

数据库中的重复项应该是409 CONFLICT

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

我在这里对4xx代码做一个较长的解释:http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/

【讨论】:

【参考方案4】:

这里是:

rfc2616#section-10.4.1 - 400 错误请求

由于格式错误,服务器无法理解请求 语法。客户端不应该不加修改地重复请求。

rfc7231#section-6.5.1 - 6.5.1。 400 错误请求

400(Bad Request)状态码表示服务器不能 或由于感知到的事情而不会处理请求 成为客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性请求路由)

指格式错误(不是格式正确)的案例!

rfc4918 - 11.2。 422 无法处理的实体

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

结论

经验法则:[_]00 涵盖最一般的情况以及指定代码未涵盖的情况。

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

400 被错误地用于对象验证

【讨论】:

【参考方案5】:

我会说从技术上讲它可能不是 HTTP 失败,因为(可能)有效地指定了资源,用户通过了身份验证,并且没有操作失败(但是即使规范确实包含一些保留代码,例如 402 Payment Required严格来说也不是与 HTTP 相关的,尽管建议在协议级别使用它,以便任何设备都可以识别这种情况)。

如果确实如此,我会在响应中添加一个状态字段,其中包含应用程序错误,例如

4日期范围无效

【讨论】:

【参考方案6】:

RFC 2616 中提供了有关这些错误语义的更多信息,该文件记录了 HTTP 1.1。

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

【讨论】:

【参考方案7】:

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

如果是这样的话,我会说 400 Bad Request 可能是正确的,但不知道你在“验证”的是什么,这是不可能的。

【讨论】:

如果我们尝试验证某些业务验证或规则该怎么办。【参考方案8】:

如果您正在验证数据而数据不是,根据已定义的规则,最好发送 422(不可处理实体),以便发件人了解他违反了约定的规则。

错误请求是针对语法错误的。 postman 等一些工具会预先显示语法错误。

【讨论】:

以上是关于REST API 服务针对验证失败返回啥适当的 HTTP 状态代码?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Azure AD 承载令牌时身份验证失败,返回容器列表 [Azure Blob] [Azure AD OAuth 2.0] [REST API]

用于重定向到 REST api 中的身份验证的适当 HTTP 状态

为 web 应用程序使用的 python REST API 选择适当的身份验证类

启用 API 身份验证时,Apache 气流 REST API 调用失败并出现 403 禁止

在啥情况下 REST API 应该返回 HTTP 状态 503

Intranet API 的 REST 身份验证缓存