身份验证令牌过期的正确HTTP代码 - 401还是403?

22

401状态码通常用于表示身份验证失败,而403则表示授权失败(也就是说身份验证成功了?) 在oauth流程中,如果我尝试使用已过期的令牌进行身份验证,那么正确的错误代码是什么,提示客户端刷新令牌并重试?


这个回答解决了你的问题吗?REST API服务在验证失败时返回什么适当的HTTP状态码? - MyStackRunnethOver
关于401和403,有很多不同的观点(比如引用的来源)。我正在寻找针对令牌过期和刷新的具体情况的权威意见。谢谢。 - user393144
https://tools.ietf.org/html/rfc7231#section-6.5.2 看起来是最权威的东西,但我担心它可能过于模糊。 - MyStackRunnethOver
3个回答

27

401状态码。401与403的混淆并不新鲜。详见此处的w3.org邮件中的一些讨论,尽管所引用的RFC 2616已经被废弃。

关于401,请参见此处

关于403,请参见此处

从401的描述中可以看出,“有效”是可以解释的:

401(未经授权)状态码表示由于缺少目标资源的有效身份验证凭据而未应用请求。

但更相关的是,请参见RFC 6750关于Bearer Token认证的第3节最后一段。 此处

并响应使用过期访问令牌进行身份验证尝试的受保护资源请求时:

 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Bearer realm="example",
                   error="invalid_token",
                   error_description="The access token expired"

22
在机场的登机流程中,有两件事需要检查:
  1. 检查你的身份证。这是认证。在线上,任何令牌或用户名/密码都代表着你的身份证。

  2. 检查你是否在那架飞机的乘客名单上(飞机是你要访问的资源)。这是授权。在线上,用户试图访问的页面代表资源。

所以现在,当你考虑一个访问问题(令牌过期,令牌解析失败,无效密码,用户不允许访问)以及你应该返回哪个HTTP状态码时,你只需要想象“如果这个问题被转移到一个机场情景,我被拒绝登机了,这与身份证检查步骤有关吗?” 如果是,那么就是401。如果不是,则是403。

例如:
  • 缺少令牌 <=> 缺少身份证 <=> 被拒绝访问,原因是身份证检查 <=> 401

  • 过期令牌 <=> 过期身份证 <=> 被拒绝访问,原因是身份证检查 <=> 401

  • 格式错误的令牌 <=> 无法读取/损坏的身份证 <=> 被拒绝访问,原因是身份证检查 => 401

  • 用户没有该资源的权限 <=> 乘客不被允许进入这架飞机 <=> 因身份证检查而被拒绝 => 403

  • 您禁止了一个用户 <=> 乘客被列入黑名单 <=> 因身份证检查而被拒绝 => 403

  • 等等。


  • 6

    TL;DR: 401

    简短版本:401表示令牌丢失或无效。403则表示令牌已通过验证,但由于某些原因被拒绝执行操作的授权。过期的令牌意味着令牌已成功解析,但其中设置的过期日期已过期。

    长版本:除了crunk1(有效)答案外:

    401表示令牌丢失或无效。换句话说,由于某种原因未能通过验证或解析。

    403表示令牌已成功验证/解析,但由于某种原因拒绝执行操作的授权。

    现在,过期的令牌意味着令牌已成功解析,但其中设置的过期日期已过期。如果考虑到检查过期日期是授权过程的一部分,这在某种程度上是介于两者之间的。就我个人而言,出于以下原因,我认为它是令牌验证的一部分,而不是授权的一部分:

    有些情况下,资源服务器(接收并验证令牌的API)甚至无法知道令牌已过期,并会返回401:

    • 如果资源服务器使用其授权服务器内省端点,并且该端点仅返回{"active": false},没有更多信息,这意味着令牌无效(它过去可能是有效的,但该信息被授权服务器“遗忘”了)。
    • 如果资源服务器尝试验证令牌签名,但令牌太旧且过期,以至于自发行以来已更新验证密钥。在这种情况下,即使令牌在语法上是有效的但已过期,RS也没有理由相信它,并应将其视为无效。

    此外,403响应会指示客户端这是授权问题,因此使用具有相同访问权限的新令牌重试的机会并不大,而401则传递了令牌未被接受的信息,因此重新尝试使用新的新鲜令牌可能会起作用。

    因此,出于以上原因,我选择在我的实现中返回401。但TBH这并不重要,因为令牌过期应该由客户端处理,基于与令牌同时返回的expires_in信息,而不是通过API的返回代码处理过期的令牌。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接