json - 安全和无状态的 JWT 实现

标签 json security http authentication jwt

背景

我正在尝试使用 JSON Web token 对我的 Web 应用程序实现 token 身份验证。

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

在尝试保持无国籍状态时,会出现一些实际的细微差别。我可以想到以下列表:

  • 在失效日期之前以每个用户为基础使受损的 token 失效。
  • 允许用户一次性退出所有机器上的所有“ session ”并立即生效。
  • 允许用户退出当前机器上的当前“ session ”并立即生效。
  • 对用户记录的权限/角色更改会立即生效。

当前策略

如果您将 JWT 中的“发布时间”声明与代表用户记录的数据库表中的“最后修改”列结合使用,那么我相信上述所有要点都可以妥善处理。

当 Web token 用于身份验证时,您可以查询数据库 以获取用户记录,并且:

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

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

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

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


问题

首先,您在上述方法中发现了任何安全漏洞吗?我遗漏的可用性问题怎么样?

一旦该问题得到解决,我真的不喜欢每次有人向安全端点发出 API 请求时都必须查询数据库,但这是我能想到的唯一策略。有没有人有更好的主意?

最佳答案

您对一些常见需求如何打破 JWT 的无状态性做了很好的分析。我只能对您当前的策略提出一些改进

Current strategy

我看到的缺点是总是需要查询数据库。对用户数据的微不足道的修改可能会改变 last_modified并使 token 无效。

另一种方法是维护 token 黑名单。通常为每个 token 分配一个 ID,但我认为您可以使用 last_modified .由于 token 的操作撤销可能很少见,您可以仅使用 userId 保留一个轻量级黑名单(甚至缓存在内存中)。 , 和 last_modified .

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

Could not sign out the action just trigger some client-side event listener to delete the cookie secure holding the JWT?

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

Are there any security flaws that you 'see in the above approach?

如果您使用 cookie,请注意您需要设置额外的保护措施以防止 CSRF 攻击。此外,如果您不需要从客户端访问 cookie,请将其标记为 HttpOnly

How about a usability issue that i am missing?

当代币即将到期时,您还需要处理轮换代币。

关于json - 安全和无状态的 JWT 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38557379/

相关文章:

javascript - 无法使用javascript eval函数解析json字符串

java - 使用阅读器架构将 Avro 文件转换为 JSON

linux - 单行异或两个字符串?

http - azure服务总线(对于主题)可以将通知发送到休息端点(POST)

sockets - 如何判断数据是否通过 HTTP 保持事件连接到达?

c# - JsonSerializerSettings 中指定的错误是否捕获所有异常

javascript - 如何将以下内容转换为有效的 JSON?

PHP session 变量安全

Linux 文本编辑器临时文件搜索

api - 基于 XML API 调用创建 Guzzle 服务定义