简体   繁体   English

REST HTTP状态代码“成功,因此您不再具有访问权限”

[英]REST HTTP status code for “success, and thus you no longer have access”

My RESTful service includes a resource representing an item ACL. 我的RESTful服务包括表示项ACL的资源。 To update this ACL, a client does a PUT request with the new ACL as its entity. 要更新此ACL,客户端将使用新ACL作为其实体执行PUT请求。 On success, the PUT response entity contains the sanitized, canonical version of the new ACL. 成功时, PUT响应实体包含新ACL的已清理的规范版本。

In most cases, the HTTP response status code is fairly obvious. 在大多数情况下,HTTP响应状态代码非常明显。 200 on success, 403 if the user isn't permitted to edit the ACL, 400 if the new ACL is malformed, 404 if they try to set an ACL on a nonexistent item, 412 if the If-Match header doesn't match, and the like. 成功时为200 ,如果不允许用户编辑ACL,则为403如果新ACL格式不正确,则为400如果尝试在不存在的项目上设置ACL,则为404如果If-Match标头不匹配,则为412 ;等等。

There is one case, however, where the correct HTTP status code isn't obvious. 但是,有一种情况,正确的HTTP状态代码并不明显。 What if the authenticated user uses PUT to remove themselves from the ACL? 如果经过身份验证的用户使用PUT从ACL中删除自己怎么办? We need to indicate that the request has succeeded but that they no longer have access to the resource. 我们需要指出请求已成功,但他们无法再访问该资源。

I've considered returning 200 with the new ACL in the PUT entity, but this lacks any indication that they no longer have the ability to GET the resource. 我考虑过在PUT实体中使用新ACL返回200 ,但是这没有任何迹象表明他们不再具有GET资源的能力。 I've considered directly returning 403 , but this doesn't indicate that the PUT was successful. 我考虑直接返回403 ,但这并不表示PUT成功。 I've considered returning 303 with the Location pointing back to the same resource (where a subsequent GET will give a 403 ), but this seems like a misuse of 303 given that the resource hasn't moved. 我已经考虑返回303Location指向同一资源(后续GET将给出403 ),但这似乎是滥用303 ,因为资源没有移动。

So what's the right REST HTTP status code for "success, and thus you no longer have access"? 那么什么是正确的REST HTTP状态代码“成功,因此您不再拥有访问权限”?

200 is the appropriate response, because it indicates success (as any 2xx code implies). 200是适当的响应,因为它表示成功(如任何2xx代码所暗示的)。 You may distinguish the user's lack of permission in the response (or, if you don't wish to, 204 is fine). 您可以区分用户在响应中缺少权限(或者,如果您不希望,则204可以)。 Status codes make no contract that future requests will return the same code: a 200 response to the PUT does not mean a subsequent GET can't return 403. In general, servers should never try to tell clients what will happen if they issue a particular request. 状态代码没有约定未来的请求将返回相同的代码:对PUT的200响应并不意味着后续的GET不能返回403.通常,服务器不应该试图告诉客户如果他们发出特定的话将会发生什么请求。 HTTP clients should almost always leap before they look and be prepared to handle almost any response code. HTTP客户端应该在它们看起来之前几乎总是跳跃并且准备好处理几乎任何响应代码。

You should read the updated description of the PUT method in httpbis ; 您应该在httpbis中阅读PUT方法更新说明 ; it discusses not only the use of 200/204 but indicates on a careful reading that returning a transformed representation in immediate response to the PUT is not appropriate; 它不仅讨论了200/204的使用,而且还仔细阅读说明,在对PUT的立即响应中返回转换后的表示是不合适的; instead, use an ETag or Last-Modified header to indicate whether the entity the client sent was transformed or not. 相反,使用ETag或Last-Modified标头来指示客户端发送的实体是否已转换。 If it was, the client should issue a subsequent GET rather than expecting the new representation to be sent in response to the PUT, if for no other reason than to update any caches along the way (because the response to a PUT is not cacheable). 如果是,客户端应该发出后续的GET而不是期望发送新的表示以响应PUT,如果没有其他原因而不是沿途更新任何缓存(因为对PUT的响应不可缓存) 。 Section 6.3.1 agrees: the response to a PUT should represent the status of the action, not the resource itself. 第6.3.1节同意:对PUT的响应应代表行动的状态,而不是资源本身。 Note also that, for a new ACL, you MUST return 201, not 200. 另请注意,对于新ACL,您必须返回201,而不是200。

You're confusing two semantic ideas, and trying to combine them into a single response code. 你混淆了两个语义思想,并尝试将它们组合成一个响应代码。

The first: That you successfully created an ACL at the location that you were attempting to. 第一个:您在尝试的位置成功创建了ACL。 The correct semantic response (in either a RESTful or non-RESTful scenario) is a 201 Created . 正确的语义响应(在RESTful或非RESTful场景中)是201 Created From the RFC: "The request has been fulfilled and resulted in a new resource being created." 来自RFC:“请求已经完成并导致创建新资源。”

The second: That the user who executed the PUT does not have access to this resource any more. 第二:执行PUT的用户不再能够访问该资源。 This is a transient idea - what if the ACL is updated, or something changes before the next request? 这是一个暂时的想法 - 如果更新ACL,或者在下一个请求之前发生了什么变化,该怎么办? The idea that a user does not have access to a resource of any kind (and this includes an ACL resource) only matters for the scope of that request. 用户无权访问任何类型的资源(这包括ACL资源)的想法仅对该请求的范围有影响。 Before the next request is executed, something could change. 在执行下一个请求之前,可能会发生一些变化。 On a single request where a user does not have access to something you should return a 403 Forbidden . 在用户无法访问某些内容的单个请求中,您应该返回403 Forbidden

Your PUT method should return a 201. If the client is worried about whether it has access any more, it should make a subsequent request to determine it's status. 您的PUT方法应该返回201.如果客户端担心它是否已经访问,它应该发出后续请求来确定它的状态。

You might want to take a look at HTTP response code "204 No Content" ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html ), indicating that the "server has fulfilled the request [to be removed from the ACL] but does not need to return an entity-body, and might want to return updated metainformation" (here, as a result of the successful removal). 您可能需要查看HTTP响应代码“204 No Content”( http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html ),表明“服务器已满足请求[将...从ACL中删除]但不需要返回实体主体,并且可能希望返回更新的元信息“(这里,由于成功删除)。 Although you're not allowed to return a message body with 204, you can return entity headers indicating changes to the user's access to the resource. 虽然您不允许使用204返回消息正文,但您可以返回实体标题,指示用户对资源的访问权限的更改。 I got the idea from Amazon S3 - they return a 204 on a successful DELETE request ( http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html ), which seems to resemble your situation since by removing yourself from an ACL, you've blocked access to that resource in the future. 我从Amazon S3得到了这个想法 - 他们在成功的DELETE请求( http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html )上返回204,这似乎与您的情况类似,因为删除您自己来自ACL,您将来阻止了对该资源的访问。

Very interesting question :-) This is why I love REST, sometimes it might get you crazy. 非常有趣的问题:-)这就是为什么我喜欢REST,有时它会让你发疯。 Reading w3 http status code definitions I would choose (this of course is just my humble opinion) one of those: 阅读w3 http状态代码定义我会选择(这当然只是我的拙见)其中一个:

  • 202 Accepted - since this mean "well yes I got your request, I will process it but come back later and see what happens" - and when the user comes back later she'll get a 403(which should be expected behavior) 202接受 - 因为这意味着“好的,我得到了你的请求,我会处理它但稍后回来看看会发生什么” - 当用户稍后回来时她会得到403(这应该是预期的行为)
  • 205 Reset Content - "Yep, I understood you want to remove yourself please make a new request, when you come back you'll get 403" 205重置内容 - “是的,我知道你想要删除自己请提出新的请求,当你回来时你会得到403”

On the other hand (just popped-up in my mind), why should you introduce a separate logic and differentiate that case and not using 200 ? 另一方面(刚刚出现在我的脑海中),为什么要引入一个单独的逻辑并区分该情况而不使用200? Is this rest going to be used from some client application that has an UI? 这个休息是否会从具有UI的某个客户端应用程序中使用? And the user of the rest should show a pop-up to the end-user "Are you sure you want to remove yourself from the ACL?" 其余的用户应该向最终用户显示弹出窗口“你确定要从ACL中移除自己吗?” well here the case can be handled if your rest returns 200 and just show a pop-up "Are you sure you want to remove user with name from the ACL?", no need to differentiate the two cases. 在这里,如果您的休息返回200并且只显示一个弹出窗口“您确定要从ACL中删除具有名称的用户吗?”,则可以处理该案例,无需区分这两种情况。 If this rest will be used for some service-to-service communication(ie invoked only from another program) again why should you differentiate the cases here the program wouldn't care which user will be removed from the ACL. 如果这个休息将用于某些服务到服务的通信(即仅从另一个程序调用),为什么要区分这里的情况,程序不关心将从ACL中删除哪个用户。

Hope that helps. 希望有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM