【问题标题】:403 Forbidden vs 401 Unauthorized HTTP responses403 Forbidden vs 401 Unauthorized HTTP 响应
【发布时间】:2011-03-18 20:15:53
【问题描述】:

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

401 Unauthorized?
403 Forbidden?
还有什么?

到目前为止,我所读到的关于两者之间的区别并不是很清楚。每种响应适合哪些用例?

【问题讨论】:

  • 401 'Unauthorized' 应该是 401 'Unauthenticated',问题解决了!
  • 我不记得我和我的同事有多少次因为这个问题回到 stackoverflow。也许 HTTP 标准应该考虑修改 401 和 403 的名称或描述。
  • @Qwerty 不,新的 RFC7231 淘汰了 RFC2616。 403 现在有了不同的含义。
  • @fishbone 您也没有注意到状态代码 401 已从该 RFC 中删除:D
  • @fishbone 它现在已被添加回该提案,但现在使用不同的 RFC 7235 tools.ietf.org/html/rfc7235#section-3.1

标签: http-headers http-status-code-403 http-status-codes http-status-code-401 http-response-codes


【解决方案1】:

来自Daniel Irvine的明确解释:

401 Unauthorized 存在问题,这是身份验证错误的 HTTP 状态代码。仅此而已:它用于身份验证,而不是授权。 收到 401 响应是服务器告诉你,“你不是 已认证 - 完全未认证或已认证 不正确 - 但请重新验证并重试。”为了帮助你, 它总是包含一个 WWW-Authenticate 标头,描述如何 进行身份验证。

这通常是由您的网络服务器返回的响应,而不是您的网络 应用。

这也是非常暂时的;服务器要求您尝试 再次。

因此,对于授权,我使用 403 Forbidden 响应。它的 永久的,它与我的应用程序逻辑相关,而且它更具体 响应比 401。

服务器收到 403 响应是在告诉您:“对不起。我知道 你是谁——我相信你说你是谁——但你只是没有 访问此资源的权限。也许如果你问系统 管理员很好,您将获得许可。但请不要打扰 直到你的困境改变为止。”

总之,401 Unauthorized 响应应该用于丢失 或错误的身份验证,应使用 403 Forbidden 响应 之后,当用户通过身份验证但未被授权时 对给定资源执行请求的操作。

另一个nice pictorial format应该如何使用http状态码。

【讨论】:

  • 默认的 IIS 403 消息是“这是一个通用的 403 错误,意味着经过身份验证的用户无权查看该页面”,这似乎是同意的。
  • @JPReddy 你的答案是正确的。但是,我希望将 401 命名为“未验证”,将 403 命名为“未授权”。与身份验证有关的 401 具有伴随文本“未经授权”的格式,这非常令人困惑......除非我的英语不好(这很有可能)。
  • @ZaidMasud,根据 RFC,这种解释是不正确的。 Cumbayah 的回答是正确的。 401 表示“您缺少正确的授权”。它意味着“如果你愿意,你可以尝试验证自己”。因此,未正确验证自己的客户端和未正确验证的客户端都会收到 401。403 的意思是“无论你是谁,我都不会回答这个问题”。 RFC 明确指出,在 403 的情况下“授权将无济于事”。
  • 401 是认证错误,403 是授权错误。就这么简单。
  • 对于所有引用 RFC(很可能是 2616)的反对者,你们都错了。正如@Idrut 在answer 中指定的那样,“禁止意味着客户端已成功验证,但未授权。”。他引用了 RFC7231 和 RFC7235,它们 过时 RFC 2616。
【解决方案2】:

编辑:RFC2616 已过时,请参阅 RFC7231RFC7235

401 未经授权:

如果请求已包含授权凭据,则 401 响应表明已拒绝对这些凭据的授权。

403 禁止:

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

从您的用例来看,用户似乎没有经过身份验证。我会返回 401。


【讨论】:

  • 谢谢,这有助于我澄清。我同时使用 401 用于未经身份验证的用户,403 用于权限不足的经过身份验证的用户。
  • 我没有投反对票,但我发现这个答案非常具有误导性。 403 禁止更适合用于永远不会提供的内容(如 asp.net 中的 .config 文件)。它要么是 404,要么是 404。恕我直言,对于可以访问但您没有正确凭据的东西返回 403 是不合适的。我的解决方案是通过更改凭据的方式提供拒绝访问消息。那个或401。
  • “响应必须包含一个 WWW-Authenticate 标头字段(第 14.47 节),其中包含适用于所请求资源的质询。”如果您不想使用 HTTP 样式的身份验证,那么 401 响应代码似乎是不合适的。
  • 我会在这里支持 Billiand。该语句是“如果请求已包含授权凭据”。这意味着如果这是来自提供凭据的请求的响应(例如来自 RFC2617 身份验证尝试的响应)。它本质上是允许服务器说,“错误的帐户/密码对,再试一次”。在提出的问题中,用户可能已通过身份验证但未授权。对于这些情况,401 绝不是适当的响应。
  • Brilliand 是对的,401 只适用于 HTTP 身份验证。
【解决方案3】:

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

简明扼要

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

意味着如果您有自己的滚动登录过程并且从不使用 HTTP 身份验证,则 403 始终是正确的响应,并且永远不应使用 401。

详细而深入

来自 RFC2616

10.4.2 401 未经授权

请求需要用户身份验证。响应必须包含一个 WWW-Authenticate 头字段(第 14.47 节),其中包含适用于所请求资源的质询。客户端可以使用合适的 Authorization 标头字段重复请求(第 14.8 节)。

10.4.4 403 禁止 服务器理解请求,但拒绝执行。授权将无济于事,并且不应重复请求。

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

因此,真正的区别不在于问题是什么,也不在于是否有解决方案。区别在于服务器期望客户端下一步做什么。

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

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


编辑:RFC2616 已过时,请参阅 RFC7231RFC7235

【讨论】:

  • 那么当用户请求一个需要非http认证的页面时,我们应该怎么做呢?发送状态码 403?
  • 这很重要:“如果您有自己的滚动登录过程并且从不使用 HTTP 身份验证,那么 403 始终是正确的响应,并且永远不应使用 401。”
  • @marcovtwout 发送 302 到您的登录页面,或发送 403 包含包含如何登录信息的正文?
  • RFC2616 应该被烧毁并被 RFC7235 取代,但据我所知,该主题没有任何变化。
  • RFC7235 不提供“roll-your-own”或替代身份验证挑战吗?为什么我的应用程序的登录流程不能以WWW-Authenticate 标头的形式提出挑战?即使浏览器不支持它,我的 React 应用程序也可以...
【解决方案4】:
+------------------------ |资源存在吗? (如果是私有的,通常在验证检查后检查) +------------------------ | | 否 | v 是 v +----------- 404 |是否已登录? (经过身份验证,又名用户会话) 或 +------------------------ 401 | | 403 否 | |是的 3xx v v 401 +------------------------ (404不透露)|可以访问资源吗? (许可,授权,...) 或 +------------------------ 重定向 | | 登录 否 | |是的 | | v v 403 OK 200,重定向,... (或 404:不显示) (或 404:如果私有资源不存在) (或 3xx:重定向)

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

  • 404 如果资源是公共的并且不存在或3xx redirection
  • 否则:
  • 如果未登录或会话过期,则为 401
  • 如果用户无权访问资源(文件、json、...),则为 403
  • 404 如果资源不存在或不愿意透露任何东西,或者3xx redirection

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

FORBIDDEN:状态码 (403) 表示服务器理解请求但拒绝执行。服务器已知但具有凭据不足的用户/代理。除非凭据更改,否则重复请求将不起作用,这在短时间内不太可能发生。 特殊情况:可以用来代替 404,以避免在暴露资源的存在暴露敏感数据或给攻击者有用信息的情况下暴露资源的存在或不存在(信用@gingerCodeNinja) .

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

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

【讨论】:

  • 如果用户没有登录或登录但没有权限,并且该内容在该位置不存在,有时您可能希望返回401/403而不是404,这样您如果用户未经过身份验证和登录,请不要公开存在或不存在的内容。仅知道存在某些内容可能会暗示某些内容或破坏 NDA。所以有时该图的 404 部分应该移到已登录/已验证。
  • @gingerCodeNinja 是的,这与 404 而不是 403 的逻辑相同,很高兴提及这种情况。
  • 感谢您提供所有级别的非常有效 no reveal 案例。当然,这在很大程度上取决于上下文,但我喜欢你已经明确表示它可能在所有这些情况下都是一个选项。
  • @MattKocaj 请注意,no reveal 案例有时可以通过细微的时间差异来检测,不应被视为一项安全功能,它可能只会减缓攻击者的速度或对隐私有所帮助。跨度>
  • 我认为您的意思是 302 而不是“301 重定向到登录”。
【解决方案5】:

根据RFC 2616 (HTTP/1.1) 403 发送时间:

服务器理解请求,但拒绝执行。授权将无济于事,并且不应重复请求。如果请求方法不是 HEAD 并且服务器希望公开请求未完成的原因,它应该在实体中描述拒绝的原因。如果服务器不希望向客户端提供此信息,则可以使用状态码 404(未找到)来代替

换句话说,如果客户端可以通过身份验证访问资源,则应该发送 401。

【讨论】:

  • 如果不清楚他们是否可以访问?假设我有 3 个用户级别 - Public、Members 和 Premium Members。假设该页面仅供高级会员使用。公共用户基本上是未经身份验证的,当他们登录时可能是会员或高级会员。对于会员用户级别,403 似乎合适。对于高级会员,401。但是,您为公众提供什么服务?
  • 恕我直言,这是最准确的答案。这取决于应用程序,但通常,如果经过身份验证的用户对资源没有足够的权限,您可能希望提供一种更改凭据或发送 401 的方法。我认为 403 最适合从未提供过的内容。在 asp.net 中,这意味着 web.config 文件 *.resx 文件等,因为无论哪个用户登录,这些文件都将永远不会被提供,因此没有必要再试一次。
  • +1,但不确定的 +1。合乎逻辑的结论是永远不应该返回 403,因为 401 或 404 将是一个更好的响应。
  • @Mel 我认为客户端不应访问的文件应该是 404。它是系统内部的文件;外界甚至不应该知道它的存在。通过返回 403,您可以让客户端知道它存在,无需将该信息泄露给黑客。 403 的规范说 An origin server that wishes to "hide" the current existence of a forbidden target resource MAY instead respond with a status code of 404 (Not Found).
  • 虽然在我看来这可能是对旧 RFC 2616 的准确解释,但请注意 RFC 7231 defines the semantics of a 403 differently,实际上明确指出 “客户端可以重复请求新的或不同的凭据。” 因此,虽然这个答案在 2010 年是准确的,但今天完全错误,因为状态代码的含义已经在我们脚下重写。 (令人讨厌的是,Changes from RFC 2616 附录不承认更改!)
【解决方案6】:

假设 HTTP 身份验证WWW-AuthenticateAuthorization 标头)正在使用,如果作为另一个身份验证用户将授予对所请求资源的访问权限,则应返回 401 Unauthorized。

403 Forbidden 用于禁止所有人访问资源或限制在给定网络或仅允许通过 SSL 访问资源,只要它与 HTTP 身份验证无关。

如果未使用 HTTP 身份验证,并且服务具有基于 cookie 的身份验证方案,这是现在的常态,则应返回 403 或 404。

关于401,这是来自RFC 7235 (Hypertext Transfer Protocol (HTTP/1.1): Authentication)

3.1。 401 未授权

401(未授权)状态码表示该请求尚未应用,因为它缺少目标资源的有效身份验证凭据。 源服务器必须发送一个 WWW-Authenticate 标头字段(第 4.4 节),其中包含至少一个适用于目标资源的质询。 如果请求包含身份验证凭据,则 401 响应表明这些凭据的授权已被拒绝。客户端可以使用新的或替换的授权头字段重复请求(第 4.1 节)。如果 401 响应包含与先前响应相同的质询,并且用户代理已经尝试了至少一次身份验证,那么用户代理应该向用户呈现封闭的表示,因为它通常包含相关的诊断信息。

403(和 404)的语义随着时间而改变。这是从 1999 年开始的 (RFC 2616):

10.4.4 403 禁止

服务器理解请求,但拒绝执行。 授权无济于事,并且不应重复请求。如果请求方法不是 HEAD 并且服务器希望公开请求未完成的原因,它应该在实体中描述拒绝的原因。如果服务器不希望向客户端提供此信息,则可以使用状态码 404(未找到)。

2014年RFC 7231 (Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content)改了403的意思:

6.5.3。 403禁止

403(Forbidden)状态码表示服务器理解请求但拒绝授权。希望公开请求被禁止的原因的服务器可以在响应负载(如果有)中描述该原因。

如果请求中提供了身份验证凭据,服务器会认为它们不足以授予访问权限。客户端不应使用相同的凭据自动重复请求。客户端可以使用新的或不同的凭据重复请求。但是,由于与凭据无关的原因,可能会禁止请求。

希望“隐藏”当前存在的禁止目标资源的源服务器可以改为响应状态码 404(未找到)。

因此,403(或 404)现在可能意味着任何事情。提供新的凭据可能会有所帮助……也可能不会。

我认为这种情况发生变化的原因是 RFC 2616 假定在当今的 Web 应用程序使用例如表单和 cookie 构建自定义身份验证方案时将使用 HTTP 身份验证。

【讨论】:

  • 这很有趣。基于 RFC 7231 和 RFC 7235,我看不出 401 和 403 之间有明显区别
  • 403 的意思是“我认识你,但你看不到这个资源”。没有理由混淆。
  • “如果请求包含身份验证凭据,则 401 响应表明这些凭据的授权已被拒绝。客户端可以使用新的或替换的授权标头字段重复请求(第 4.1 节)。”但是,然后是“4.2. 'Authorization' 标头字段允许用户代理向原始服务器验证自己”。看起来在 RFC7235 中他们使用术语“授权”,就像它是“身份验证”一样。在这种情况下,经过身份验证但未经授权的用户似乎不应该得到 401,而是 403
  • @Brian 主要区别是,如果您的系统使用 RFC 7235 中指定的 HTTP 身份验证,则返回 401(因此您必须返回带有此类响应的 WWW-Authenticate 标头)和 403否则。
  • @MichaelBlackburn 不,事实并非如此。服务器不需要知道您返回 403。一方面,旧的 RFC 2616 规范和较新的 RFC 7231 规范都没有这样说;另一方面,新规范中的短语 "If 身份验证凭据已在请求中提供" 只有在某些情况下可能返回 403 时才有意义 不请求中包含身份验证凭据(即服务器绝对不“认识你”的情况)。
【解决方案7】:
  • 401 Unauthorized:我不知道你是谁。 这是一个身份验证错误。
  • 403 Forbidden:我知道你是谁,但你没有访问此资源的权限。 这是一个授权错误。

【讨论】:

  • 不确定它“总是”意味着发件人未知。只是他们要求的一切都没有得到授权。
  • 虽然您的解释看起来很有说服力,但我不满意或不信任它,因为错误 401 表示名称本身的授权,而您正在与身份验证混合使用。好吧,我可以告诉一个场景,使用我获得令牌的凭据意味着成功通过身份验证,并使用它来访问该令牌的“未经授权的资源”。那是未经授权的 401。对此你有什么想说的?
  • @Jasmine 你的担心是可以理解的,但是上面的解释是正确的。术语冲突是由 http 规范不符合当前广泛使用的术语“身份验证”和“授权”定义引起的。可能是由于这些定义没有像现在这样普遍使用。我们被冲突及其引起的混乱所困扰。支持这一点的证据是浏览器的默认行为是在 401 响应中提示输入凭据。
  • 这是对已接受答案中描述的区别的精辟总结。但是,就像公认的答案一样,这完全是错误的。 HTTP 规范中没有任何内容支持这种区别,对于典型的网站登录系统,使用返回 401 的 WWW-AuthenticateAuthorization 标头根本不允许。跨度>
【解决方案8】:

这是一个较老的问题,但从未真正提出的一个选项是返回 404。从安全角度来看,投票最高的答案可能会受到 information leakage vulnerability 的影响。例如,有问题的安全网页是系统管理页面,或者更常见的是,是系统中用户无权访问的记录。理想情况下,您甚至不希望恶意用户知道那里有页面/记录,更不用说他们无权访问了。当我构建这样的东西时,我会尝试在内部日志中记录未经身份验证/未经授权的请求,但返回 404。

OWASP 有一些more information,关于攻击者如何使用此类信息作为攻击的一部分。

【讨论】:

  • 之前的答案中已经提到了 404 的使用。您说得对:信息泄漏,这对于任何推出自己的身份验证/授权方案的人来说应该是一个重要的考虑因素。 +1 提及 OWASP。
  • 具有讽刺意味的是,OWASP 链接现在转到 404 页面。我在owasp.org/index.php/… 上发现了类似的东西(我认为)
  • 取决于 API 以及如何授予访问权限。但是“泄漏”不是问题,如果它返回 401 的用户名/密码肯定与 Web 表单相同?
【解决方案9】:

这个问题是前段时间提出的,但人们的想法还在继续。

此草稿中的Section 6.5.3(由 Fielding 和 Reschke 撰写)赋予状态代码 403 与 RFC 2616 中记录的含义略有不同的含义。

它反映了许多流行的网络服务器和框架所采用的身份验证和授权方案中发生的情况。

我已经强调了我认为最突出的一点。

6.5.3。 403禁止

403(Forbidden)状态码表示服务器理解请求但拒绝授权。希望公开请求被禁止的原因的服务器可以在响应负载(如果有)中描述该原因。

如果请求中提供了身份验证凭据,服务器会认为它们不足以授予访问权限。 客户端不应使用相同的凭据重复请求。客户端可以使用新的或不同的凭据重复请求。但是,由于与凭据无关的原因,可能会禁止请求。

希望“隐藏”当前存在的禁止目标资源的源服务器可以改为响应状态码 404(未找到)。

无论您使用什么约定,重要的是在您的网站/API 中提供统一性。

【讨论】:

  • 草案获得批准,现在是 RFC 7231。
【解决方案10】:

!!! DEPR:答案反映了 2014 年之前的常见做法!!!

TL;DR

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

实例

如果 apache 需要身份验证(通过.htaccess),并且您点击Cancel,它将以401 Authorization Required 响应

如果 nginx 找到一个文件,但没有访问权限(用户/组)来读取/访问它,它将以403 Forbidden

响应

RFC(2616 第 10 节)

401 未经授权 (10.4.2)

意思一:需要认证

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

含义2:身份验证不足

...如果请求已包含授权凭证,则 401 响应表示已拒绝对这些凭证的授权。 ...

403 禁止 (10.4.4)

含义:与身份验证无关

...授权无济于事...

更多细节:

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

它应该在实体中描述拒绝的原因

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

(如果服务器想对客户端保留此信息)

【讨论】:

  • 您的“授权将无济于事”引用自 2014 年 6 月以来已过时的规范。tools.ietf.org/html/rfc7231 替换了它并说相反 - “客户可以用新的重复请求或不同的凭据。” 因此,现在绝对可以在“需要进行身份验证”和“身份验证不足”的情况下使用 403 响应。
  • 谢谢!如果你愿意,你可以编辑答案。现在我在顶部放了一个弃用警告。
【解决方案11】:

这些是含义:

401:用户未(正确)认证,资源/页面需要认证

403:用户的角色或权限不允许访问请求的资源,例如用户不是管理员,请求的页面是管理员的。

注意:从技术上讲,403 是 401 的超集,因为为未经身份验证的用户提供 403 也是合法的。反正区分更有意义。

【讨论】:

  • 这是对这个问题的一个很好的 TLDR 答案。
  • 这个写的很清楚,直截了当,但是错了。当用户未通过身份验证时,返回 403s 是完全可以的。规范中没有其他说明,而且通常您不能在这种情况下使用 401,因为只有在包含 WWW-Authenticate 标头时返回 401 才是合法的。
  • tx @MarkAmery ,我稍微更正了句子以包括可能的身份验证
【解决方案12】:

他们没有登录或不属于正确的用户组

您已经陈述了两种不同的情况;每个案例应该有不同的反应:

  1. 如果他们根本没有登录,你应该返回 401 Unauthorized
  2. 如果他们已登录但不属于正确的用户组,则应返回 403 Forbidden

关于基于收到此答案的 cmets 的 RFC 的注释:

如果用户未登录,则他们未经身份验证,其 HTTP 等价物是 401,并且在 RFC 中被误导性地称为未经授权。正如section 10.4.2 声明的401 Unauthorized

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

如果您未经身份验证,则 401 是正确的响应。但是,如果您未经授权,在语义上正确的意义上,403 是正确的响应。

【讨论】:

  • 这是不正确的。请参阅RFC 和@Cumbayah 的回答。
  • @DavideR。 RFC 交替使用 authenticationauthorization。我相信用 authentication 的含义阅读它会更有意义。
  • 这个答案是相反的。未经授权与未经身份验证不同。 @DavideR 是对的。身份验证和授权不可互换
  • 2616 应该被烧掉。几个较新的 RFC 更清楚地表明,需要区分“我不认识你”和“我认识你,但你不能访问它”。 没有正当理由承认存在永远不会被实现(或无法通过 http 实现)的资源,这是 403-truthers 所建议的。
【解决方案13】:

英文:

401

您可能被允许访问,但出于某种原因,您在此请求中被允许访问 否认。比如密码错误?再试一次,请求正确 你会得到一个成功的响应。

403

你永远不被允许。你的名字不在名单上,你不会 永远进入,离开,不要发送重试请求,它将被拒绝, 总是。走开。

【讨论】:

  • 不是真的。 current spec's description of 403 声明 “客户端可以使用新的或不同的凭据重复请求。”,这与您在此处对 403 的描述相矛盾。
  • @MarkAmery“使用新的或不同的凭据重复”好的,所以我的答案仍然有效,因为新的或不同的请求不是“重试”是吗?如果您以自己的用户身份登录并获得 403,然后再试一次,您将获得 403。如果您以 Admin 用户注销并重新登录,现在却获得 200,这不是重试请求。这是一个完全不同的请求,具有不同的凭据。所以我的回答仍然有效,“你”是不允许的,“你的”名字不在名单上,“你”永远不会进入,“不要发送重试请求”。使用不同的凭据不是“重试”,而是新请求。
【解决方案14】:

这在我的脑海中比这里的任何地方都简单,所以:

401:您需要 HTTP 基本身份验证才能看到此内容。

403:您看不到这一点,HTTP 基本身份验证也无济于事。

如果用户只需要使用您站点的标准 HTML 登录表单登录,则 401 将不合适,因为它特定于 HTTP 基本身份验证。

我不建议使用 403 来拒绝对 /includes 之类的访问,因为就网络而言,这些资源根本不存在,因此应该使用 404。

这会将 403 保留为“您需要登录”。

换句话说,403 表示“此资源需要某种形式的身份验证,而不是 HTTP 基本身份验证”。

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2

【讨论】:

    【解决方案15】:

    我认为重要的是要考虑到,对于浏览器,401 会启动一个身份验证对话框,让用户输入新的凭据,而 403 不会。浏览器认为,如果返回 401,则用户应该重新进行身份验证。所以 401 代表无效认证,而 403 代表没有权限。

    在这种逻辑下,有些情况会从身份验证或授权中返回错误,其中重要的短语用粗体显示。

    • 资源需要身份验证,但没有凭据指定

    401:客户端应指定凭据。

    • 指定的凭据采用无效格式

    400:这既不是 401 也不是 403,因为语法错误应该总是返回 400。

    • 指定的凭据引用了一个不存在用户

    401:客户端应指定有效凭据。

    • 指定的凭据无效,但指定了有效用户(如果不需要指定用户,则不指定用户)。

    401:同样,客户端应指定有效凭据。

    • 指定的凭据过期

    401:这实际上与一般的无效凭据相同,因此客户端应指定有效凭据。

    • 指定的凭据完全有效,但不能满足特定的资源,尽管具有更多权限的凭据可能会。

    403:指定有效凭据不会授予对资源的访问权限,因为当前凭据已经有效但没有权限。

    • 无论凭据如何,特定的资源都是无法访问的。

    403:这与凭据无关,因此指定有效凭据无济于事。

    • 指定的凭据完全有效,但特定的客户端阻止使用它们。

    403:如果客户端被阻止,指定新凭据将不会执行任何操作。

    【讨论】:

      【解决方案16】:

      我已经为您创建了一个简单的注释,它将清楚地说明。

      【讨论】:

        【解决方案17】:

        鉴于有关此事的最新 RFC(72317235),用例似乎很清楚(添加了斜体字):

        • 401 用于unauthenticated(“缺少有效的身份验证”);即“我不知道你是谁,或者我不相信你就是你所说的那个人。”

        401 未经授权

        401(未授权)状态码表示请求没有 已应用,因为它缺少有效的身份验证凭据 目标资源。生成 401 响应的服务器必须发送 包含至少一个 WWW-Authenticate 头字段(第 4.1 节) 适用于目标资源的挑战。

        如果请求包含身份验证凭据,则 401 响应表明授权已被拒绝 证书。用户代理可以使用新的或 替换了授权头字段(第 4.2 节)。如果 401 响应包含与先前响应相同的挑战,并且 用户代理已经至少尝试过一次身份验证,然后 用户代理应该向 用户,因为它通常包含相关的诊断信息。

        • 403 为unauthorized(“拒绝授权”);即“我知道你是谁,但你无权访问此资源。”

        403 禁止

        403(Forbidden)状态码表示服务器理解 请求但拒绝授权。一个服务器希望 公开请求被禁止的原因可以描述 响应负载中的原因(如果有)。

        如果请求中提供了身份验证凭据,则 服务器认为它们不足以授予访问权限。客户端 不应以相同的方式自动重复请求 证书。客户端可以用新的或不同的重复请求 证书。但是,由于某些原因,请求可能会被禁止 与凭据无关。

        希望“隐藏”当前存在的源服务器 禁止的目标资源可以改为以状态码响应 404(未找到)。

        【讨论】:

        • -1;这些段落已在此处的其他答案中被引用,而您的则没有增加任何新内容。我认为显然清楚区别是什么;您将这两个代码总结为“缺乏有效的身份验证”和“拒绝授权”,但我无法想象在任何情况下,其中一个简短描述将适用,而另一个无法解释为适用。
        • 这里有很多答案,涵盖了许多 RFC,并且经过编辑和更新,弄得一团糟。我提供了一个链接来解释 authenticated 是什么以及 authorized 是什么,并保留了所有过时的 RFC,以便清楚地了解应用程序。
        • 您的编辑澄清了您对这两个代码的解释,这似乎与许多其他人的解释相符。但是,我个人认为这种解释意义不大。在 403 描述中使用短语 如果 提供了身份验证凭据” 意味着即使没有提供凭据,403 也可能是合适的 - 即“未经身份验证”的情况.同时,对我来说,对 401 描述中包含的短语 “for the target resource” 最自然的解释是,401 可用于经过身份验证但未授权的用户。
        【解决方案18】:

        在 401 vs 403 的情况下,这个问题已经回答了很多次了。这本质上是一场“HTTP 请求环境”的辩论,而不是一场“应用程序”的辩论。

        似乎有关于 roll-your-own-login 问题(应用程序)的问题。

        在这种情况下,仅仅没有登录并不足以发送 401 或 403,除非您使用 HTTP Auth 与登录页面(与设置 HTTP Auth 无关)。听起来您可能正在寻找“201 Created”,其中存在一个滚动您自己的登录屏幕(而不是请求的资源),用于应用程序级对文件的访问。这说:

        “我听说了,它就在这里,但是试试这个(你不能看到它)”

        【讨论】:

        • 究竟创建了什么?
        猜你喜欢
        • 2012-03-02
        • 2023-01-25
        • 2023-01-20
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-14
        • 2018-11-06
        相关资源
        最近更新 更多