RESTful登录失败:返回401或自定义响应


103

这是一个概念性的问题。

我有一个客户端(移动)应用程序,需要支持针对RESTful Web服务的登录操作。因为Web服务是RESTful的,所以这意味着客户端接受了用户的用户名/密码,并通过该服务验证了该用户名/密码,然后只是记得随所有后续请求一起发送该用户名/密码。

此Web服务中的所有其他响应均以JSON格式提供。

问题是,当我查询Web服务只是为了确定给定的用户名/密码是否有效时,Web服务是否应始终以JSON数据响应以告知其成功或不成功,还是应返回具有良好凭据和HTTP的HTTP 200 401错误的凭据。

我问的原因是,即使您只是在询问凭证是否有效,其他一些RESTful服务也使用401来提供不良凭证。但是,据我对401响应的理解,它们代表一种资源,如果没有有效的凭据,您不应访问这些资源。但是任何人都应该可以访问登录资源,因为登录资源的全部目的是告诉您您的凭据是否有效。

换句话说,在我看来,这样的请求:

myservice.com/this/is/a/user/action 

如果提供了错误的凭据,则应返回401。但是这样的请求:

myservice.com/are/these/credentials/valid

永远不要返回401,因为该特定的URL(请求)是使用有效凭据或不使用有效凭据进行授权的。

我想听一听,对此有一些合理的看法。处理此问题的标准方法是什么?逻辑上适当的处理方法是什么?

Answers:


128

首先。401是登录失败时发送的正确响应代码。

401未经授权 与403禁止类似,但专门用于需要身份验证且失败或尚未提供身份验证的情况。响应必须包含一个WWW-Authenticate标头字段,其中包含适用于所请求资源的质询。

您感到困惑,myservice.com/are/these/credentials/valid只是在执行检查时才发回401,我认为这是基于以下事实:在RESTful约束下,在REST中执行布尔请求通常是错误的。每个请求都应返回一个资源。在RESTful服务中执行布尔型问题对于RPC来说是一个滑溜的循环。

现在,我不知道您所查看的服务的行为方式。但是解决此问题的一种好方法是让您尝试获取诸如Account对象之类的东西。如果您的凭据是正确的,则将获得Account对象,如果您不想浪费带宽仅用于“检查”,则可以在同一资源上执行HEAD。

帐户对象也是存储所有讨厌的布尔值的好地方,否则这些值将很难创建单个资源。


2
您关于返回资源的观点似乎是正确的,也许这是正确的举动。至于声明401是正确的响应,我希望在此进行一些解释。我已经阅读了HTTP规范,就像您在此处包含的一样,但是对我而言,这并不表示您对声明的直接,明显的确认。也就是说,不需要身份验证就可以询问凭据的有效性-但是您所输入的内容是“专门用于需要身份验证的情况”。
马特2012年

3
您看待它的方式是正确的。您无需通过身份验证即可请求您的Account对象。但是您需要成功进行身份验证才能接收资源,这就是authentication is required and has failed or has not yet been provided适用的地方,因为您不要求凭据的有效性,而是要求根据您提供的凭据的特定资源。
Cleric

2
我知道您为什么要进行“检查呼叫”,为此,我仍然将401提升为失败的身份验证的适当响应代码,即使该呼叫不需要身份验证即可调用。204 No Content也可能适用,但感觉有点含糊。
Cleric

4
除非您使用基本或摘要身份验证,否则我看不出这怎么正确。按照规范的引用部分:“响应必须包含WWW-Authenticate”-如果您参考14.47节:“ HTTP访问认证过程在“ HTTP认证:基本和摘要访问认证”中进行了描述。这意味着对我来说,如果您使用的是典型的电子邮件/密码验证,则401不适合
Jonah

1
我认为这可能是错误的,我一直在实现Web和移动客户端,并且拦截401以重定向到登录屏幕。但是,当某人已经在登录屏幕上并提交了错误的凭据时,响应也将显示401,并将尝试再次重定向。对于显式尝试时无法通过身份验证的尝试,应该使用不同的状态代码。可能是错误的请求,甚至是服务器错误?
Japheth Ongeri-inkalimeva

28

仅当请求需要授权头字段并且授权失败时,才发送401。由于Login API不需要授权,因此我认为401是错误的错误代码

根据此处的标准https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401未经授权

该请求需要用户认证。响应必须包括一个WWW-Authenticate头域(第14.47节),其中包含适用于所请求资源的质询。客户可以用适当的授权头域(第14.8节)重复请求。如果请求已包含授权凭证,则401响应指示已拒绝这些凭证的授权。如果401响应包含与先前响应相同的质询,并且用户代理已经尝试了至少一次身份验证,则应向用户提供响应中给定的实体,因为该实体可能包括相关的诊断信息。HTTP访问身份验证在“ HTTP身份验证:基本和摘要访问身份验证” [43]中进行了说明。*


8
我对此表示同意,但是要发送的替代回复状态是什么?我一直在实现网络和移动客户端,我拦截401以重定向到登录屏幕。但是,当某人已经在登录屏幕上并提交了错误的凭据时,响应中还会显示401,并将尝试再次重定向...您会怎么做?
Japheth Ongeri-inkalimeva

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.