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

Mat*_*att 90 rest login http http-response-codes

这是一个概念性问题.

我有一个客户端(移动)应用程序,需要支持针对RESTful Web服务的登录操作.由于Web服务是RESTful,这相当于客户端接受用户的用户名/密码,验证服务的用户名/密码,然后只记得发送该用户名/密码以及所有后续请求.

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

问题是,当我查询Web服务只是为了找出给定的用户名/密码是否有效时,Web服务是否总是以JSON数据响应,告诉我它成功或不成功,或者它应该返回HTTP 200的良好凭据和HTTP 401凭据不良凭证.

我问的原因是,即使您只是询问凭据是否有效,其他一些RESTful服务也会使用401作为错误的凭据.但是,我对401响应的理解是,它们代表了一个没有有效凭据就无法访问的资源.但是登录资源应该对任何人都可以访问,因为登录资源的全部目的是告诉您凭据是否有效.

换句话说,在我看来,请求如下:

myservice.com/this/is/a/user/action 
Run Code Online (Sandbox Code Playgroud)

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

myservice.com/are/these/credentials/valid
Run Code Online (Sandbox Code Playgroud)

永远不应该返回401,因为该特定URL(请求)在有或没有有效凭据的情况下被授权.

我想在这方面听到一些合理的意见.处理这个问题的标准方法是什么,这是处理逻辑上合适的标准方法吗?

Cle*_*ric 109

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

401 Unauthorized 类似于403 Forbidden,但专门用于需要验证且失败或尚未提供的情况.响应必须包含WWW-Authenticate头字段,其中包含适用于所请求资源的质询.

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

现在我不知道你看到的服务是如何表现的.但解决这个问题的一个好方法是使用类似于Account对象的东西来尝试获取.如果您的凭据是正确的,您将获得Account对象,如果您不想浪费带宽只是为了"检查",您可以在同一资源上执行HEAD.

帐户对象也是存储所有那些讨厌的布尔值的好地方,否则创建单个资源会很棘手.

  • 你看待它的方式是正确的.您无需进行身份验证即可申请帐户对象.但是您需要成功进行身份验证才能接收资源,并且那里需要"身份验证失败或尚未提供"的情况适用,因为您不要求凭据的有效性,而是针对特定资源根据您提供的凭据. (3认同)
  • 除非您使用的是基本身份验证或摘要身份验证,否则我看不出这是如何正确的.根据规范的引用部分:"响应必须包含WWW-Authenticate" - 如果您参考第14.47节:"HTTP身份验证:基本和摘要访问身份验证中描述了HTTP访问身份验证过程."这意味着对我来说,如果你使用典型的电子邮件/密码验证,401是不合适的. (3认同)
  • 关于返回资源的观点似乎是有效的,也许这是正确的举措.至于说401是正确的反应,我会在那里得到一些解释.我已经阅读了HTTP规范,正如您在此处所包含的那样,但对我而言,这并不是对您的断言的直接和明显的确认.也就是说,不需要身份验证来询问凭证的有效性 - 但您所包含的内容是"专门用于需要身份验证时使用". (2认同)
  • 我理解你为什么要进行"检查",为此,我仍然会将401作为失败认证的相应响应代码,即使调用不要求身份验证可以调用.A 204 No Content可能也适合,但感觉有点含糊不清. (2认同)

vin*_*rma 18

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

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

*10.4.2 401未经授权

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

  • 我同意你的意见,但是发送的替代响应状态是什么?我一直在实现网络和移动客户端,我拦截401重定向到登录屏幕.但是当某人已经在登录屏幕上并提交了错误的凭据时,响应也有401并且会再次尝试重定向...你会怎么做? (7认同)

han*_*ter 6

当由于请求缺少凭据或凭据不正确而拒绝访问资源时,使用http 状态代码是合乎逻辑的。当提供正确的凭据时,请求应该成功完成,授予对受保护资源的访问权限。 适用于您的情况:。401
myservice.com/this/is/a/user/action

也许我们应该清楚这个凭证

在大多数安全应用程序中,需要凭据才能访问受保护的资源。这些凭证可以通过 HTTP 标头与每个请求一起发送。特别是Authorization标题
因此,授权标头包含允许用户访问受保护资源的凭据

请记住,成功验证为授权用户(成功登录)的用户将被授予此特权凭据以允许访问服务器上受保护的资源。

从服务器的角度来看,针对受保护资源但缺少凭据 包含无效 凭据的 HTTP 请求可能会导致有效地发回401响应代码

因此,登录 API 不应401因登录尝试失败而发送响应代码。这是误导性的。推断您正在通过登录 API 请求服务器应用程序授予您访问受保护资源所需的凭据。就其本身而言,登录 API 并不是保护的资源。

那么什么是正确的响应状态呢?

好吧,我会建议发回400响应代码,因为失败的登录尝试是客户端错误,因为客户端错误没有提供正确的用户名或密码

根据RFC标准大约400个代码:

400(错误请求)状态代码表示服务器由于被认为是客户端错误的原因而无法或不会处理请求(例如,格式错误的请求语法、无效的请求消息帧或欺骗性请求路由)

我再次重申,登录失败是由于提供的详细信息不正确而导致的客户端错误。发回 400 并不一定意味着请求语法格式错误。但格式错误的语法是原因之一。

发送 401 确实会产生误导,因为用户不需要提供身份验证信息来访问登录 API。