RFC 6749 第 5.2 节 (http://tools.ietf.org/html/rfc6749#section-5.2) 描述了错误响应。 它说服务器应该以 HTTP 400(错误请求)响应。 但是 oauthlib 使用 HTTP 401(未经授权)代替InvalidClientError
、 InvalidGrantError
、 UnauthorizedClientError
和其他相关错误等错误。
例如https://github.com/idan/oauthlib/blob/master/oauthlib/oauth2/rfc6749/errors.py#L181
规范提到 401 可能与无效的客户端错误一起使用,并且必须在通过授权标头字段完成身份验证时使用。 尽管 oauthlib 目前没有建议按照规范要求将“WWW-Authenticate”标头字段包含在响应中。 我认为为这个错误保留 401 是可以的,但我们应该在异常中添加一个标题建议。
关于另一个,规范没有明确说明可以使用 401,因此我们可能应该考虑更改为 400。但是,在无效授权和尤其是未经授权的客户端错误中,使用 401 似乎更合适。
@asteinlein , @lepture , @masci 的想法?
@ib-lundgren 嗨 - 刚刚偶然发现这个问题并想插话。通过阅读规范并查看其他答案,IMO a 400 是正确的响应。
首先,规格:
授权服务器响应 HTTP 400(错误请求)
状态码(除非另有说明)并包括以下内容
响应参数:
400 条要求中没有 MUST,但也没有 MAY。
其次,我偶然发现这个的原因是通过我客户端上的 sun JDK 中的一个错误(见这里:http://stackoverflow.com/a/7524681/1137254)
本质上,我的客户端的 HTTP 堆栈会提前关闭 401 连接,但上面的 OAuth 堆栈(google-http-oauth-client)会尝试继续读取并解析结果。 我认为这是根据 401 的定义和期望写入 OpenJDK 的(更新:它实际上与“流”模式有关)。 IMO OpenJDK 也是错误的,如果我在 /token 端点请求期间获得“invalid_client”401,我想我会遇到同样的问题。
在此处添加另一票 400 是正确的错误代码。 我们曾经使用 django-oauth2-provider 从移动应用程序进行 oauth2 身份验证,在这种情况下它返回 400。 当切换到 django-oauth-toolkit(它使用 oauthlib)以升级到更新的 Django 版本时,我们不得不破解令牌请求视图以返回 400 来保持移动应用程序正常工作。
这是该规范的作者之一,特别指出 400 是在请求令牌时对无效身份验证凭据的预期响应,以及原因: https ://www.ietf.org/mail-archive/web/oauth/current/msg02127
+1 为 400
投票给 400
我正在恢复这个旧线程并使用上面建议的更改开始 PR。
在取得进展之前,我想总结一下过去发生的讨论。
WWW-Authenticate
,而且并非总是在所有错误响应中都可能。401
都必须是400
。 但是,我们有两种情况401
:invalid_client
,如果使用 HTTP 身份验证,它必须是401
,否则它可能是401
。invalid_token
,它应该是401
。在任何情况下,如果使用401
,则必须设置WWW-Authenticate
( RFC2616 )。
最常见的 OAuth2.0 实现的快速概览类似于总体共识:
400
so-question / so-question 。400
salesforce-forum 。WWW-Authenticate
azur-docs返回401
。400
aws-cognito-docs 。 当使用 HTTP 身份验证时,他们将 RFC 的“ MUST ”打破为401
。我们必须与 RFC 保持一致,但是为了不破坏任何实现,我们不能在 2.xx 版本中包含这些更改,而是等到 3.xx
请随意插话。
我不记得让我推动 PR #247 的原因/客户,但我看到并理解了恢复它的原因。 感谢@JonathanHuot的出色研究,在 3.x 中执行此操作听起来是最好的方法。
已在 #561 / oauthlib>= 3.0.0 中修复
根据上面提到的这个 RFC 无效客户端也应该返回状态 400 但在包中仍然是 401
嗨@esfandiaryfard ,你能指出RFC的确切文本吗? 谢谢!
最有用的评论
在取得进展之前,我想总结一下过去发生的讨论。
WWW-Authenticate
,而且并非总是在所有错误响应中都可能。401
都必须是400
。 但是,我们有两种情况401
:invalid_client
,如果使用 HTTP 身份验证,它必须是401
,否则它可能是401
。invalid_token
,它应该是401
。在任何情况下,如果使用
401
,则必须设置WWW-Authenticate
( RFC2616 )。其他 OAuth2.0 实现
最常见的 OAuth2.0 实现的快速概览类似于总体共识:
400
so-question / so-question 。400
salesforce-forum 。WWW-Authenticate
azur-docs返回401
。400
aws-cognito-docs 。 当使用 HTTP 身份验证时,他们将 RFC 的“ MUST ”打破为401
。结论
我们必须与 RFC 保持一致,但是为了不破坏任何实现,我们不能在 2.xx 版本中包含这些更改,而是等到 3.xx
请随意插话。