【发布时间】:2016-10-14 12:35:08
【问题描述】:
我喜欢 JWT 的简单性,并且只是在为 Web 应用程序实现身份验证机制时使用它们,其中我有一个 Elixir/Phoenix 后端,它提供一个 RESTful JSON API 和一个 Angular 2 前端。
今天我偶然发现了this 文章(我绝不隶属于该网站),它让我对 JWT 的使用产生了一些疑问,我想讨论一下。主要是:
- 没有真正的方法可以在不关闭的情况下使 JWT 失效 整个系统。至少当他们是无国籍的时候。
- 这意味着您无法撤消访问权限,这可能非常糟糕。
- LocalStorage - JWT 主要存储在前端 - 不如会话存储安全。
与 cookie 不同,本地存储不会发送您的数据内容 存储每个请求。检索数据的唯一方法 本地存储是使用 JavaScript,这意味着任何攻击者 提供的通过内容安全策略的 JavaScript 可以访问 并将其渗出。不仅如此,JavaScript 也不关心或 跟踪数据是否通过 HTTPS 发送。就 JavaScript 而言 担心,它只是数据,浏览器会像这样操作它 它会是任何其他数据。
在这些工程师经历了所有的麻烦以确保没有人之后 将使用我们的饼干罐,这里我们试图忽略 他们给我们的所有花哨的技巧。这似乎有点倒退 对我来说。
到目前为止,我认为他的观点是无效的——只要一个人通过 https 提供所有服务并防止 XSS 和 CORS 攻击。我的意思是如果可以在站点上执行恶意 JS,这真的不是 JWT 的问题。并且 JS 不允许混合内容(http 和 https)。
为了使所有令牌无效:只需使用 JWT 代号变量之类的东西,它可以存在于您的环境变量中并在每个令牌中进行编码。它是一个简单的整数。如果要使所有令牌无效,请增加它。然后你只需要一个机制来检查代号是否匹配。这不必影响数据库,也不应该是性能问题。并且使用可靠的部署策略在多个实例上推出它应该不会太难。
为了使单个令牌无效:使用刷新令牌和 JWT 的生命周期非常短(几分钟)。如果 JWT 的 TTL 快结束了,用户会通过刷新令牌获得一个新的。这意味着每几分钟就有一次数据库命中。
还是我弄错了?
【问题讨论】:
-
"这真的不是 JWT 的问题" --- 不是,但是你丢失了一个令牌并且你没有简单的方法来使其无效。
-
“使用刷新令牌和非常短的 JWT 生命周期” --- 如果你丢失了它,有人可以无限期地恶意刷新它。 “这意味着每几分钟就有一次 DB 命中。” --- 那么你就不需要 JWT 并且可以使用普通会话。
-
@zerkms 首先:您将如何处理丢失令牌?如果您不使用 SSL,它可能会被拦截。但这对于 Cookies 也是如此,并且只是会话劫持。但是假设它发生了:使用刷新令牌策略,您可以轻松地使单个令牌无效。你的第二个论点是,如果你每隔几分钟就访问一次数据库,你也可以使用会话:我不同意。 JWT 有更多的优势,然后只是最大限度地减少对 DB 的命中。而且每隔几分钟仍然比每次请求都要好很多。
-
"如果丢失令牌,您将如何处理?" --- XSS
-
嗯,XSS 是一个完全不同的话题。如果您的网站容易受到 XSS 攻击,那不是 JWT 的错,无论如何您都会遇到大问题。