【问题标题】:Correct HTTP code for authentication token expiry - 401 or 403?验证令牌到期的正确 HTTP 代码 - 401 还是 403?
【发布时间】:2017-12-22 13:17:30
【问题描述】:

401 似乎用于指示身份验证失败,而 403 用于指示授权失败(这意味着身份验证成功?) 在 oauth 流的情况下,如果我尝试使用过期令牌进行身份验证,提示客户端刷新令牌并重试的正确错误代码是什么?

【问题讨论】:

标签: http-authentication


【解决方案1】:

TL;DR:401

加长版,除了crunk1(有效)答案:

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

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

现在,过期的令牌意味着令牌已成功解析,但该令牌中设置的过期日期已过。如果您认为检查到期日期是授权过程的一部分,那么这有点介于两者之间。我个人认为这是令牌验证的一部分,而不是授权的一部分,原因如下:

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

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

此外,403 响应将指示客户端这是一个授权问题,因此使用带有相同访问权限的新令牌重试成功的机会不大,而 401 将传递令牌的信息不被接受,所以也许用新的令牌重试可能会奏效。

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

【讨论】:

    【解决方案2】:

    想想机场的登机流程。他们检查两件事:

    1. 他们会检查您的身份证。这是身份验证。在网上,任何令牌或用户/密码对都代表您的身份证。

    2. 他们检查您是否在该飞机的乘客列表中(该飞机是您尝试访问的资源)。这是授权。在线,用户尝试访问的页面代表资源。

    所以现在当您考虑访问问题(令牌已过期、令牌解析失败、密码无效、用户不被允许)以及您应该返回哪个 HTTP 代码时,您只需要考虑“如果这个问题被转移到机场我被拒绝进入飞机,这与身份证检查步骤有什么关系吗?”如果是,这是 401。如果不是,这是 403。

    例如:

    • 缺少令牌<=>缺少身份证<=>因身份证检查而被拒绝<=>401

    • 过期令牌<=>过期身份证<=>因身份证检查而被拒绝<=>401

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

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

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

      李>

    【讨论】:

      【解决方案3】:

      A 401。401 与 403 的混淆并不新鲜。请在此处查看 w3.org 电子邮件中的一些讨论:https://lists.w3.org/Archives/Public/ietf-http-wg/2008AprJun/0418.html,尽管引用的 RFC 2616 已过时。

      关于 401,请参阅 https://www.rfc-editor.org/rfc/rfc7235#section-3.1

      关于 403,请参阅 https://www.rfc-editor.org/rfc/rfc7231#section-6.5.3

      从 401 描述来看,虽然“有效”有待解释:

      401(未授权)状态码表示请求没有 已应用,因为它缺少 有效 身份验证凭据 目标资源。

      但更重要的是,请参阅 RFC 6750 关于承载令牌认证的第 3 节最后一段。 https://www.rfc-editor.org/rfc/rfc6750#section-3

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

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

      【讨论】:

        猜你喜欢
        • 2017-12-11
        • 2020-11-09
        • 1970-01-01
        • 2021-04-02
        • 1970-01-01
        • 2015-10-21
        • 2019-06-05
        • 2014-12-14
        • 2021-08-22
        相关资源
        最近更新 更多