JWT是用户身份验证的安全选择吗? [英] Are JWTs a secure option for user authentication?

查看:376
本文介绍了JWT是用户身份验证的安全选择吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢JWT的简单性,并在为Web应用实现身份验证机制时使用了它们,其中我有一个Elixir/Phoenix后端,该后端提供RESTful JSON API和Angular 2前端.

I like the simplicity of JWTs and just used them when implementing an authentication mechanism for an web app where I have an Elixir/Phoenix backend that serves a RESTful JSON API and an Angular 2 frontend.

今天,我偶然发现了文章(我绝不隶属于本网站),这使我对要讨论的JWT的使用产生了一些疑问.主要是:

Today I stumbled about this article (I'm in no way affiliated with this website) and it gave me some doubts about the use of JWT which I would like to discuss. Mainly:

  • 在不关闭JWT的情况下,没有真正的方法使JWT失效 整个系统.至少当他们是无国籍的时候.
  • 这意味着您无法撤消访问权限,这可能非常糟糕.
  • LocalStorage(JWT主要存储在前端侧)不如会话存储安全.
  • There is no real way of JWTs to be invalidated without shutting down the whole system. At least when they are stateless.
  • That means you cannot revoke access, which could be very bad.
  • LocalStorage - where JWTs are mostly stored on the front-end side - is not as secure as Session Storage.

与cookie不同,本地存储不会发送数据内容 存储每个请求.从中检索数据的唯一方法 本地存储是通过使用JavaScript来实现的,这意味着任何攻击者 通过内容安全策略的提供的JavaScript可以访问 并把它偷走.不仅如此,JavaScript也不在乎或 跟踪是否通过HTTPS发送数据.至于JavaScript 只是数据,浏览器会像这样操作 其他任何数据.

Local storage, unlike cookies, doesn’t send the contents of your data store with every single request. The only way to retrieve data out of local storage is by using JavaScript, which means any attacker supplied JavaScript that passes the Content Security Policy can access and exfiltrate it. Not only that, but JavaScript also doesn’t care or track whether or not the data is sent over HTTPS. As far as JavaScript is concerned, it’s just data and the browser will operate on it like it would any other data.

在经历了所有麻烦之后,那些工程师确保没有人 将与我们的饼干罐脱节,在这里我们试图忽略 他们给我们的所有花哨的技巧.似乎有些倒退 给我.

After all the trouble those engineers went through to make sure nobody is going to make off with our cookie jar, here we are trying to ignore all the fancy tricks they’ve given us. That seems a little backwards to me.

到目前为止,我认为他的观点是无效的-只要有人通过https提供一切服务并防止XSS和CORS攻击.我的意思是,如果可以在站点上执行恶意JS,那么这实际上不是JWT的问题.而且JS不允许混合内容(http和https).

So far I think his points are not valid - as long as one serves everything via https and protects against XSS and CORS attacks. I mean if malicious JS can be executed on the site this is really not a problem of JWT. And JS does not allow mixed content (http and https).

用于使所有令牌无效:只需使用JWT世代号变量之类的变量即可,它可以存在于您的环境变量中,并在每个令牌中进行编码.它是一个简单的整数.如果要使所有令牌无效,请增加它.然后,您只需要一种机制来检查世代号是否匹配.这不必打数据库,也不应该是性能问题.而且,采用可靠的部署策略将其扩展到多个实例应该并不难.

For invalidating all tokens: Just use something like a JWT generation-number variable, that could live in your environment variables and is encoded in every token. It is a simple integer. If you want to invalidate all tokens, increment it. Then you just need a mechanism to check if the generation number matches. This doesn't have to hit the DB and shouldn't be a performance issue. And it shouldn't be too difficult to roll this out over multiple instances with a solid deployment strategy.

要使单个令牌失效:请使用刷新令牌,并且JWT的使用寿命非常短(几分钟).如果JWT的TTL快要用完了,则用户可以通过刷新令牌获得一个新的TTL.这意味着数据库每隔几分钟就会命中一次.

For invalidating a single token: Use refresh tokens and a very short lifespan for a JWT (couple of minutes). If the TTL of the JWT is almost over, the user get's a new one via the refresh token. This means a DB hit every couple of minutes.

还是我弄错了?

推荐答案

LocalStorage-JWT主要存储在前端侧-是 不如会话存储安全.

LocalStorage - where JWTs are mostly stored on the front-end side - is not as secure as Session Storage.

您始终可以将JWT存储在 HttpOnly Cookie 内,这将降低以下风险:它们被任何XSS漏洞偷走了.

You could always store your JWTs within HttpOnly cookies, which will mitigate the risk of them being stolen by any XSS vulnerability.

当然,所有其他通常的最佳实践都适用-安全标志,HSTS等.

Of course all the other usual best practices apply - secure flag, HSTS, etc.

用于使所有令牌失效:只需使用JWT之类的东西 世代号变量,可能存在于您的环境中 变量并编码在每个令牌中

For invalidating all tokens: Just use something like a JWT generation-number variable, that could live in your environment variables and is encoded in every token

是的,您可以这样做,甚至完全生成新的秘密.

Yes, you could do that or even generate new secrets entirely.

要使单个令牌无效:对于JWT,请使用刷新令牌和非常短的寿命 (几分钟).如果JWT的TTL即将耗尽,则用户 通过刷新令牌获得一个新的.这意味着每个数据库都会命中一个 几分钟.

For invalidating a single token: Use refresh tokens and a very short lifespan for a JWT (couple of minutes). If the TTL of the JWT is almost over, the user get's a new one via the refresh token. This means a DB hit every couple of minutes.

所以我假设这意味着对您的刷新令牌使用传统的服务器端会话状态机制?这似乎是一种有效的方法.使用安全算法(例如SHA-2-无需添加盐),确保会话令牌已在服务器端进行了哈希处理.

So I'm assuming this means using traditional server-side session state mechanisms for your refesh-tokens? This seems a valid approach. Ensure the session tokens are hashed server-side though with a secure algorithm (e.g. SHA-2 - no salt is required).

唯一棘手的部分是从客户端到服务器的时钟同步.如果您要快速使它们过期,那么任何小的时钟差异都可能使客户端感到困惑,并且它们将不会及时请求刷新令牌.这使事情变得更加复杂,而复杂性是安全性的主要敌人.

The only tricky part is clock synchronisation from client to server. If you're expiring them quickly, then any small clock differences may confuse the client and they won't request the refresh token in time. This is making things more complicated, and complexity is the main enemy of security.

如果您要如此快地过期令牌,那么使用传统的服务器端会话管理机制可能更有意义.

If you're expiring tokens so quickly, it would probably make more sense to use traditional server-side session management mechanisms.

这篇关于JWT是用户身份验证的安全选择吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆