在查看问题“Correct HTTP status code when resource is available but not accessible because of permissions”的同时受到思想的启发,我将使用相同的场景来说明我的假设问题。
想象一下,我正在建立一个拼车网络服务。
假设以下
GET /api/persons/angela/location
检索用户“angela”的当前位置。只有angela本人和可能会选择她的驱动程序应该能够知道她的位置,因此如果请求未通过相应用户的身份验证,则会返回401 Unauthorized响应。
还要考虑请求
GET /api/persons/john/location
当没有用户名为john时已向系统注册。没有john资源,更不用说john位置的资源了,所以这显然会返回404 Not Found。或者是吗?
如果我不想透露john是否已在系统中注册,该怎么办?
(也许用户名来自一小部分大学登录,并且校园里有一个非常激进的自行车小组,即使你在拼车,也会对车辆的使用情况非常暗淡?他们可以向URL发出请求对于每个用户,如果他们收到401而不是404,则推断该用户是汽车用户)
为此请求返回401 Unauthorized是否有意义,即使资源不存在且在请求中没有可能提供的凭据集以使服务器返回200?< / p>
答案 0 :(得分:24)
实际上,W3C recommends(RFC2616§10.4.4403Forbidden)正好相反。如果有人试图访问资源但未经过适当的身份验证,则返回404,而不是403(Forbidden)。这仍然解决了信息披露问题。
如果服务器不想制作 这些信息可供使用 客户端,状态代码404(不是 找到了)可以代替使用。
因此,你永远不会返回403(或401)。但是,我认为您的解决方案也是合理的。
编辑:我认为加布是在正确的轨道上。你必须重新考虑部分设计,但为什么不呢:答案 1 :(得分:8)
如果用户名是敏感信息,则不要将它们直接放在URI中。如果您在表示中使用超媒体,那么您可以使授权客户端应用程序轻松导航您的API而不会泄露您的URL中的信息。
Hackable网址非常适合您希望每个人都能轻松访问的信息。但是,对于RESTful客户端,使用完全不透明的URI没有问题。
删除用户与URI之间的直接关联后,很难从401响应代码中推断出任何信息。
答案 2 :(得分:1)
如果您希望在不是用户的客户端发出请求时返回401 Unauthorized,我认为没问题。但是,如果用户发出请求并进行身份验证,那么我认为401不是最佳解决方案。如果您觉得返回404会损害某些用户的安全性,那么您可能需要考虑返回403 Forbidden或者200 OK,但是不要指定位置。如果我查询用户bob并获得响应并查询用户sam并获得错误响应,无论是401,403,404等,那么我可能得出结论,这意味着用户sam不存在。
200 OK没有指定位置可能是最伪装的解决方案。
编辑:只是为了说明我的建议。如果客户端未获得授权,则返回401。否则,总是返回200 OK。
<user-location for="bob">
<location>geo-coordinates here</location>
</user-location>
<user-location for="sam">
<location/>
</user-location>
这并不能说明sam是否存在,或者当前可能没有任何位置数据。
答案 3 :(得分:1)
我认为最好的解决方案是为类中的每个(潜在)页面返回403(禁止),如果用户未经过身份验证以查看其中任何一个。如果用户是,则返回404以查找不存在的内容,并返回200内容。
答案 4 :(得分:1)
在任何不允许用户查看特定网页的情况下返回401 Unauthorized
。
来自RFC 2616:“如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据。”
考虑使用单独的凭据列表对不同URL进行身份验证的HTTP服务器。显然,服务器不应该在请求URL时检查每个列表,因此如果凭据不在那个适用的列表中,因为HTTP请求完全相互独立,所以返回401 Unauthorized
是有意义的。如果凭据对该特定网址无效。
此外,403 Forbidden的描述包括:“授权无效,请求不应重复。” 相反,如果用户选择使用正确的凭据登录,则授权将帮助。