Ger*_*áth 28 security authentication access-token jwt refresh-token
我已经读了一段时间了,没有任何意义,而且解释相互矛盾,评论证明了这一点。
到目前为止,我的理解是 JWT 存储由服务器编码的信息,可以有过期时间,并且服务器及其密钥可以解码其中的信息(如果它有效)。说得通。
它对于可扩展性很有用,因此独立的 API 可以解码并验证令牌中的信息,只要它们拥有密钥。此外,不需要将信息存储在任何数据库中,这与会话不同。说得通。
如果令牌被盗,API 无法判断令牌是否由正确的人使用。这是上面的缺点。
通过减少令牌的过期时间,可以减少安全漏洞,从而减少窃贼未经许可使用令牌的时间。(附带问题,但如果他们能够偷一次,他们可能也会偷第二次)
但是减少令牌的有效时间意味着每次令牌过期时用户都需要登录,并且如上所述,这种情况相当频繁,因此不会提供太好的用户体验。说得通。
从现在开始,一切都没有意义了:
引入刷新令牌可以解决这个问题,因为它的过期时间更长。使用刷新令牌可以生成访问令牌,因此只要用户拥有刷新令牌(时间较长)就可以登录,而被盗的访问令牌仍然仅在短时间内有效。
对我来说,上述内容似乎增加了一层额外的复杂性,而安全性没有任何改进。即对我来说,上面的内容似乎等于一个长期存在的访问令牌。
为什么?因为对我来说,刷新令牌基本上是一个访问令牌(因为这就是它生成的)。因此,拥有刷新令牌意味着无限制的访问令牌,因此无限制地访问 API。
然后我读到一个答案,刷新令牌和访问令牌是一对一的映射,因此窃取访问令牌仍然意味着对 API 的未经授权的访问,但只持续很短的时间,并且窃取刷新令牌将生成不同的访问令牌,以便 API 可以检测到异常(同一帐户使用不同的访问令牌),从而使访问令牌失效。
看来我不是唯一一个对这个问题感到困惑的人。
如果上述情况不正确,刷新令牌有何真正帮助?
如果上述情况成立,并且确实存在刷新令牌和访问令牌的一对一映射:
如果有人能澄清这个问题那就太好了,因为从 5 个解释中,有 5 个相互冲突的陈述(有时相同的解释包含冲突的信息),并且许多开发人员都想了解这种方法。
Gab*_*yel 14
基于令牌的身份验证存在普遍的混乱,因此让我们尝试澄清其中一些问题。
首先,JWT 不仅由服务器“编码”,而且还“签名”(更准确地说,通常是消息身份验证)。目的是这样的令牌不能被客户端或任何人更改或改变,因此令牌中的任何字段(声明)都可以被信任为发行者创建它的样子,否则验证将失败。
这产生了两个重要的结论:
如果这样的令牌包含主题的某种身份(用户,如用户 ID 或电子邮件地址)和过期时间,则可以使用它来维护没有服务器端状态的会话。
另一个重要的收获是:
此外,JWT 令牌通常以客户端代码 (javascript) 可以访问的方式存储,因此客户端应用程序可以读取用户是谁以及令牌何时过期等信息。不一定如此,但大多数实现都是这样做的,例如。将其存储在本地存储中。这使得这些令牌容易受到 XSS 攻击,这意味着任何成功的 XSS 都将能够获取令牌。
由于到目前为止讨论的原因,JWT 身份验证本质上不如普通的旧会话安全,只有在需要时才应使用。很多时候,当使用令牌身份验证时,实际上并不是必需的,只是一种幻想。
有时,这样的令牌存储在 httpOnly cookie 中,但在这种情况下,令牌不能发送到多个源(localStorage 的一个好处),并且也可以使用普通的旧会话 ID,并且实际上会更安全。
好的,那么什么是刷新令牌。正如您正确指出的那样,限制访问令牌的生命周期对于限制受损令牌的有效性很有用。因此,当旧的访问令牌过期时,可以使用刷新令牌来获取新的访问令牌。关键是这些存储在哪里。
一个关键要点:
在更好的架构中,可能会发生以下情况:
可以有这样的实现变体,但要点是上面的,对两个令牌的访问的分离。
正如您所描述的,刷新令牌到访问令牌的一对一映射是不寻常的,也是不必要的,但实际上有时每个用户一个会话是必需的(特别是在您想要进行非常清晰的审计的金融应用程序中)用户所做的事情的踪迹)。但这和上面讨论的事情没有太大关系。
同样如上所述,以无状态方式正确注销(会话失效)是不可能的。幸运的是,很少有应用程序实际上需要在服务器端实现真正的无状态。
| 归档时间: |
|
| 查看次数: |
7054 次 |
| 最近记录: |