首页 文章

安全和无状态的JWT实施

提问于
浏览
4

背景

我正在尝试使用JSON Web令牌在我的Web应用程序中实现令牌身份验证 .

无论我最终使用什么策略,我都会尝试维护两件事:无状态和安全性 . 但是,通过阅读本网站上的答案和互联网上的博客文章,似乎有些人确信这两个属性是互斥的 .

在试图维持无国籍状态时,有一些实际的细微差别 . 我可以想到以下列表:

  • 在到期日之前,基于每个用户使受损令牌无效 .

  • 允许用户立即在所有计算机上注销所有"sessions"并使其立即生效 .

  • 允许用户在当前计算机上注销当前"session"并立即生效 .

  • 对用户记录进行权限/角色更改会立即生效 .


当前战略

如果您在JWT中使用“已发布时间”声明并结合表示用户记录的数据库表中的“最后修改”列,那么我相信可以优雅地处理上述所有要点 .

当Web令牌进入身份验证时,您可以 query the database 获取用户记录,并且:

if (token.issued_at < user.last_modified) then token_valid = false;

如果您发现有人侵犯了用户的帐户,则用户可以更改其密码,并且可以更新 last_modified 列,从而使之前发布的任何令牌无效 . 这也解决了权限/角色更改不会立即生效的问题 .

此外,如果用户请求立即注销所有设备,那么您猜对了:更新 last_modified 列 .

这留下的最后一个问题是每个设备注销 . 但是,我相信这甚至不需要去服务器,更不用说去数据库了 . 注销操作无法触发一些客户端事件监听器来删除持有JWT的安全cookie吗?


问题

首先,您在上述方法中是否存在任何安全漏洞?我失踪的可用性问题怎么样?

一旦这个问题得到解决,我真的不喜欢每次有人向安全 endpoints 发出API请求时都要查询数据库,但这是我能想到的唯一策略 . 有没有人有更好的想法?

1 回答

  • 3

    您已经很好地分析了一些常见需求如何打破JWT的状态 . 我只能对你目前的战略提出一些改进建议

    目前的战略

    我看到的缺点是总是需要对数据库进行查询 . 对用户数据进行微不足道的修改可能会更改 last_modified 并使令牌无效 .

    另一种方法是维护令牌黑名单 . 通常会为每个令牌分配一个ID,但我认为您可以使用 last_modified . 由于令牌的操作撤销可能很少见,因此只需 userIdlast_modified 就可以保留一个浅黑名单(甚至缓存在内存中) .

    您只需在更新用户(密码,权限等)和 currentTime - maxExpiryTime < last_login_date 上的关键数据后设置条目 . 当 currentTime - maxExpiryTime > last_modified (不再发送未过期的令牌)时,可以丢弃该条目 .

    无法退出操作只是触发一些客户端事件监听器删除持有JWT的cookie安全?

    如果您在具有多个打开选项卡的同一浏览器中,则可以使用localStorage事件在选项卡之间同步信息以构建注销机制(或登录/用户已更改) . 如果您的意思是不同的浏览器或设备,那么您需要从服务器向客户端发送某种方式的事件 . 但这意味着维护一个活动通道,例如WebSocket,或者向本机移动应用程序发送推送消息

    您在上述方法中是否存在任何安全漏洞?

    如果您使用的是cookie,请注意您需要针对 CSRF 攻击设置额外保护 . 此外,如果您不需要从客户端访问cookie,请将其标记为 HttpOnly

    我失踪的可用性问题怎么样?

    当接近到期时,您还需要处理旋转令牌 .

相关问题