我正在尝试使用JWT为我的RESTful API实现无状态身份验证.
AFAIK,JWT基本上是在REST调用期间作为HTTP头传递的加密字符串.
但是,如果有一个窃听者看到了请求并窃取了令牌呢?那么他能用我的身份伪造请求吗?
实际上,这种关注适用于所有基于令牌的身份验证.
怎么预防?像HTTPS这样的安全渠道?
我是一个节点库的作者,它在很大程度上处理身份验证,表达stormpath,所以我会在这里提供一些信息.
首先,JWT通常不加密.虽然有一种方法可以加密JWT(参见:JWE),但由于许多原因,这在实践中并不常见.
接下来,任何形式的身份验证(使用JWT或不使用JWT)都会受到MitM攻击(中间人)攻击.当您通过互联网发出请求时,攻击者可以查看您的网络流量,就会发生这些攻击.这是您的ISP可以看到的,NSA等.
这有助于防止以下情况:通过加密来自计算机的NETWORK流量 - >某些服务器在进行身份验证时,监控网络流量的第三方无法看到您的令牌,密码或类似内容,除非他们能够以某种方式获取服务器私有SSL密钥的副本(不太可能).这就是SSL对所有形式的身份验证都是强制性的原因.
但是,假设有人能够利用您的SSL并且能够查看您的令牌:您的问题的答案是肯定的,攻击者将能够使用该令牌冒充您并向您的服务器发出请求.
现在,这是协议的来源.
JWT只是身份验证令牌的一个标准.它们可以用于几乎任何东西.JWT很酷的原因是你可以在其中嵌入额外的信息,你可以验证没有人搞乱它(签名).
但是,JWT本身与"安全"无关.对于所有意图和目的,JWT与API密钥或多或少相同:只是随机字符串,用于在某处对某个服务器进行身份验证.
是什么让你的问题更有趣,是使用的协议(很可能是OAuth2).
OAuth2的工作方式是,它旨在为客户提供TEMPORARY令牌(如JWT!),以便在短时间内进行身份验证!
我们的想法是,如果您的令牌被盗,攻击者只能在短时间内使用它.
使用OAuth2时,您必须经常通过提供用户名/密码或API凭据,然后以交换方式获取令牌来重新对服务器进行身份验证.
因为这个过程经常发生,所以你的令牌会经常变化,让攻击者更加难以不经常冒犯你.
希望这有助于^^
我知道这是一个老问题,但我想我可以在这里降低0.50美元,可能有人可以改进或提供一个论据来完全拒绝我的方法.我在HTTPS(ofc)的RESTful API中使用JWT.
为了实现这个目标,你应该总是发行短期令牌(取决于大多数情况,在我的应用程序中,我实际上将exp
声明设置为30分钟,并且ttl
为3天,所以只要它ttl
仍然可以刷新此令牌有效且令牌未被列入黑名单)
对于authentication service
,为了使令牌无效,我喜欢使用内存缓存层(在我的情况下为redis)作为JWT blacklist
/ ban-list
在前面,取决于一些标准:(我知道它打破了RESTful哲学,但存储的文件是真的很短暂,因为我将剩余的生存时间列入黑名单 - ttl
索赔- )
注意:黑名单令牌无法自动刷新
如果user.password
或user.email
已经更新(需要密码确认),auth服务将返回刷新的令牌并使之前的令牌无效(黑名单),因此如果您的客户端检测到用户的身份已被某种方式泄露,您可以要求该用户更改其密码.如果您不想使用黑名单,您可以(但我不鼓励您)验证iat
(发布时)对user.updated_at
字段的声明(如果jwt.iat < user.updated_at
JWT无效).
用户故意退出.
最后,您通常会像每个人一样验证令牌.
注2:我建议为声明生成和使用UUID令牌,而不是使用令牌本身(实际上很长)作为缓存的密钥jti
.哪个好,我想(不确定,因为它只是出现在我的脑海中)你可以使用同样的UUID作为CSRF令牌,通过返回一个secure
/ non-http-only
cookie并X-XSRF-TOKEN
使用js 正确实现头.这样您就可以避免为CSRF检查创建另一个令牌的计算工作.
抱歉,在此方面晚了一点,但有类似的担忧,现在想在同一点上有所作为。
1)rdegges补充了一个很好的观点,即JWT与“安全性”无关,并且仅验证是否有人弄乱了有效载荷(签名);ssl有助于防止违规。
2)现在,如果ssl也以某种方式受到威胁,任何窃听者都可以窃取我们的不记名令牌(JWT)并冒充真正的用户,下一步可以做的是,从客户端寻求JWT 的“拥有证明”。
3)现在,通过这种方法,JWT的演示者拥有一个特定的所有权证明(POP)密钥,接收者可以通过密码确认该请求是否来自同一真实用户。
为此,我提到了所有权证明一文,并对方法深信不疑。
如果能够做出任何贡献,我将很高兴。
欢呼声(y)