对于存在但用户没有足够权限(他们未登录或不属于正确的用户组)的网页,要提供的正确HTTP响应是什么?

401未授权?403禁止?还有别的吗?

到目前为止,我读到的每一篇文章都不太清楚两者之间的区别。每个响应都适合哪些用例?


当前回答

我已经为您创建了一个简单的注释,它将使您明白。

其他回答

  +-----------------------
  | RESOURCE EXISTS ? (if private it is often checked AFTER auth check)
  +-----------------------
    |       |
 NO |       v YES
    v      +-----------------------
   404     | IS LOGGED-IN ? (authenticated, aka user session)
   or      +-----------------------
   401        |              |
   403     NO |              | YES
   3xx        v              v
              401            +-----------------------
       (404 no reveal)       | CAN ACCESS RESOURCE ? (permission, authorized, ...)
              or             +-----------------------
             redirect          |            |
             to login       NO |            | YES
                               |            |
                               v            v
                               403          OK 200, redirect, ...
                      (or 404: no reveal)
                      (or 404: resource does not exist if private)
                      (or 3xx: redirection)

检查通常按以下顺序进行:

404如果资源是公共的且不存在或3xx重定向否则:401如果未登录或会话已过期403如果用户没有访问资源的权限(文件、json…)404如果资源不存在或不愿意透露任何信息,或3xx重定向

未授权:状态代码(401)指示请求需要身份验证,通常这意味着用户需要登录(会话)。服务器未知的用户/代理。可以使用其他凭据重复。注意:这令人困惑,因为它应该被命名为“未经验证”而不是“未经授权”。如果会话过期,登录后也可能发生这种情况。特殊情况:可以代替404使用,以避免显示资源的存在或不存在(credits@jiangCodeNinja)

禁止:状态代码(403),表示服务器理解请求但拒绝执行。服务器知道用户/代理,但没有足够的凭据。除非凭据更改,否则重复请求将不起作用,这在短时间内是非常不可能的。特殊情况:可以使用404代替404,以避免在显示资源的存在暴露敏感数据或向攻击者提供有用信息的情况下显示资源(credits@jiangCodeNinja)的存在或不存在。

未找到:状态代码(404),指示请求的资源不可用。用户/代理已知,但服务器不会透露任何有关资源的信息,就像它不存在一样。重复不起作用。这是404的一个特殊用法(例如github)。

如@ChrisH所述,有几个3xx重定向选项(301、302、303、307或根本不重定向,使用401):

HTTP重定向代码之间的差异浏览器缓存HTTP 301多长时间?重定向到登录页面时,正确的HTTP状态代码是什么?302和307重定向之间有什么区别?

!!! DEPR:答案反映了直到2014年以前的普遍做法!!!

TL;博士

401:与身份验证有关的拒绝403:拒绝与身份验证无关

实际示例

如果apache需要身份验证(通过.htaccess),并且您单击“取消”,则它将响应401“所需授权”

如果nginx找到了一个文件,但没有读取/访问该文件的访问权限(用户/组),那么它将响应403 Forbidden

RFC(2616第10节)

401未授权(10.4.2)

含义1:需要认证

请求需要用户身份验证。。。

含义2:身份验证不足

…如果请求已经包括授权凭证,则401响应指示已拒绝对这些凭证的授权。。。

403禁止(10.4.4)

含义:与身份验证无关

…授权没有帮助。。。

更多详情:

服务器理解该请求,但拒绝履行该请求。

应说明实体拒绝的原因

可以改用状态代码404(未找到)

(如果服务器希望将此信息保留给客户端)

其他答案缺少的是,必须理解RFC 2616上下文中的认证和授权仅指RFC 2617的HTTP认证协议。HTTP状态代码不支持RFC2617以外的方案进行认证,并且在决定是否使用401或403时不考虑。

Brief和Terse

未授权表示客户端未通过RFC2617认证,服务器正在启动认证过程。Forbidden表示客户端已通过RFC2617认证且没有授权,或者服务器不支持请求资源的RFC2617。

也就是说,如果您拥有自己的登录过程,并且从不使用HTTP身份验证,那么403始终是正确的响应,而401永远不应该使用。

详细和深入

来自RFC2616

10.4.2 401未授权请求需要用户身份验证。响应必须包括WWW Authenticate报头字段(第14.47节),该字段包含适用于所请求资源的质询。客户端可以使用适当的授权头字段重复请求(第14.8节)。

and

10.4.4 403禁止服务器理解该请求,但拒绝履行。授权不会有帮助,不应重复该请求。

首先要记住的是,本文档中的“身份验证”和“授权”特指RFC 2617中的HTTP身份验证协议。它们不引用您可能使用登录页面等创建的任何滚动您自己的身份验证协议。我将使用“登录”来引用除RFC2617以外的方法进行的身份验证和授权

因此,真正的区别不在于问题是什么,甚至不在于是否有解决方案。区别在于服务器希望客户端接下来做什么。

401指示无法提供资源,但服务器正在请求客户端通过HTTP身份验证登录,并已发送回复标头以启动进程。可能存在允许访问资源的授权,也可能没有,但让我们尝试一下,看看会发生什么。

403指示不能提供资源,并且对于当前用户来说,没有办法通过RFC2617来解决这一问题,也没有尝试的意义。这可能是因为已知没有足够的认证级别(例如,由于IP黑名单),但也可能是因为用户已经认证且没有权限。RFC2617模型是一个用户,一个证书,因此可以忽略用户可能具有可被授权的第二组证书的情况。它既不暗示也不暗示某种登录页面或其他非RFC2617认证协议可能有帮助,也可能没有帮助,这超出了RFC2616标准和定义。


编辑:RFC2616已过时,请参阅RFC7231和RFC7235。

你又是谁??(程序员走进一个没有ID或ID无效的酒吧)

403:太好了,又是你。我盯着你了。走吧,离开这里。(程序员走进一家86岁的酒吧)

401未经授权:我不知道你是谁。这是一个身份验证错误。403禁止:我知道你是谁,但你没有访问此资源的权限。这是一个授权错误。