JWT-使用jsonwebtoken的最佳方法是什么?我迷路了

时间:2019-06-20 19:34:03

标签: node.js express authentication jwt restful-authentication

我现在学习编码已有一年了。我主要学习了如何处理其余的API(后端的Node / Express和前端的Vue)。

我到了要发展自己对应用程序的想法的地步。

为此,我首先要开发后端以具有身份验证过程,该过程可以用作我将要进行的其他项目的样板。

但是现在我完全不了解Jsonwebtoken以及如何正确使用它来确保安全和用户友好。

到目前为止,我知道rest API应该是无状态的(即,任何东西都不应该存储在服务器端,因此不应进行DB调用(例如会话)来授予对数据的访问权限。)

在这方面,我注意到了不同的策略:

  • 短期JWT:(+)这非常安全,因为从理论上来说,每次访问服务器时都必须登录(-)非常糟糕的用户体验

  • JWT寿命长:(+)用户友好(永久登录)(-)非常不安全(无法检查JWT是否被盗)

  • 具有长期刷新令牌的短期JWT ...

那是我感到困惑的地方……

从我阅读的每篇文章/教程中,刷新令牌都应以某种方式与数据库链接(例如,存储刷新令牌密钥或列入黑名单的令牌…)。我还看过一个教程,该教程将秘密密钥(用于验证令牌)与数据库中存储的哈希密码部分链接在一起。这很聪明,因为从用户更改密码起,以前的令牌将自动被视为无效……但这再次意味着DB调用……

我的意思是我得出的结论是 (1)没有完美的方法来以安全且用户友好的方式处理身份验证过程… (2)无法避免DB调用具有某些安全性...

考虑到这个结论,我绝对不理解刷新令牌的使用...

如果刷新令牌需要数据库调用,则只需一个主令牌就可以达到相同的结果……

例如,您可以在令牌和DB中存储一个JWT ID。如果在验证令牌时这两个ID匹配,则发出一个新令牌,其新ID会覆盖先前的ID。现在,如果您使用旧版本,它将永远不会被验证...然后,由于您已调用DB来验证令牌(最肯定是USER表),因此您可以同时检查例如用户是否为管理员(不需要)将其存储在JWT中)…最后,您可以使用上述的“哈希密码”技巧来增强安全性……

所以……我想念什么?最佳策略是什么?

很高兴收到您对此的评论(或链接到一篇非常好的文章-尽管我有很多……)

非常感谢您的帮助

PS:我什至没有在谈论如何将令牌发送到服务器(带有cookie,但存在CSRF附加或带有标头的风险,但是如果将令牌存储在客户端,则可能遭受XSS攻击)…在这方面,我已经看到多个教程,这些教程通过带有cerf密钥的cookie通过JWT通过客户端存储在客户端以及在jet =>内部都应发送。

PS2:我希望我很清楚,因为我是说法语的本地人:-)

1 个答案:

答案 0 :(得分:0)

因此您在这一问题中问了很多问题。任何人都很难在这里给出一个深思熟虑的答案,但我会尽力的。在此之前,完全免责声明,我是一个名为SuperTokens的新库的作者,我相信它将为您提供会话管理的最佳解决方案。您可能已经阅读了我们的博客:https://hackernoon.com/all-you-need-to-know-about-user-session-security-ee5245e6bdad。最好是我们可以聊一聊,以便为您提供所有有关您所问问题的详细解释(我想为您提供帮助)。加入我们的纷争:https://discord.gg/zVcVeev

现在回答您的问题:

  • 您应该始终只使用短暂的JWT

  • 执行数据库调用以进行身份​​验证不是问题,但是与其他所有操作一样,我们会尝试优化操作,因此减少数据库调用会更好。如果您使用JWT访问令牌和不透明刷新令牌,那么对于大多数API而言,您不需要执行db调用。但是,如果您将JWT的秘密密钥与哈希密码链接在一起,则必须为每个API进行数据库调用-可以,但是我觉得没有必要,因为无论如何您都将使用短暂的JWT(几个小时)最多一天)

  • 您提到了令牌盗窃-这是一个棘手的问题,但是根据RFC 6819,您可以使用旋转刷新令牌的概念来检测盗窃。当然,实际上这样做可能很棘手,因为您必须照顾许多竞争状况和网络故障问题-请参阅https://hackernoon.com/the-best-way-to-securely-manage-user-sessions-91f27eeef460

  • 关于我们为什么需要刷新令牌的原因:假设您没有刷新令牌,那么您将只有一个可以同时被视为访问令牌和刷新令牌的令牌。您仍然可以使它短暂存在(当它是一个访问令牌时),然后在它过期后,将其视为刷新令牌-也有一定寿命。这样做的问题是,它不是很干净(令牌过期的要点是之后它就没用了),并且每个API调用都在网络上公开刷新令牌,从而降低了安全性。我知道您可以使用HTTPS,但是也存在HTTPS MITM攻击-请参阅博客文章的第1部分。

  • 在存储方面,一个巧妙的技巧可能是将访问令牌拆分为两个-一个存储在安全的httponly cookie中,另一个存储在localstorage中。对于每个API调用,都将两者都发送到服务器(无论如何都会自动发送cookie),然后服务器会将两者结合起来并进行身份验证。这样可以同时防止CSRF和XSS攻击!

现在,您既可以自己实现整个过程,也可以使用我们的库来完成所有这些工作:https://github.com/supertokens/supertokens-node-mysql-ref-jwt

要进一步讨论此问题或您有任何其他问题,请加入我们的不和谐服务器。

PS:我知道我用它来宣传我的音乐库,但希望我确实回答了您的问题。在不进行交谈的情况下,很难对您的问题做出很好的解释。