我应该/如何将我的 JWT 令牌存储在 redis 中以便我可以看到当前的用户会话?

Posted

技术标签:

【中文标题】我应该/如何将我的 JWT 令牌存储在 redis 中以便我可以看到当前的用户会话?【英文标题】:How should/could I store my JWT tokens in redis so that I can see current user sessions? 【发布时间】:2016-12-16 07:03:33 【问题描述】:

我正在使用 Java 和 Spring 来构建一个 rest api 以及其他一些服务。

主要功能是创建/登录用户。我知道 redis 中没有查询语言,这就是我在这里发布问题的原因! Java 中是否有某种库允许我们查询 Redis?在我的情况下,获取分配给用户 (userId) 的所有当前 jwt 令牌(会话)?

我自己想到了一个实现,但我认为它有点过头和笨重?

    我会使用 userId 作为键 然后,我会将 JWT 令牌的 hashmap 存储在 value 部分中。

例子

    用户登录 我们创建 JWT 我们创建一个 hashmap,然后添加 JWT 然后我们将 hashmap 作为字节数组分配给 redis 键 (userId) 我们会保存 redis 键+值

如果同一个用户登录,我将不得不再次通过并执行以下操作:

    创建 JWT 使用 userId 搜索现有的 redis 键 然后我们将找到的值转换为我们的初始 JWT 对象 然后我们将另一个 JWT 对象添加到 hashmap 保存键+值

这意味着在每个对受保护 api 端点的请求中,我必须通过 userId 进行搜索、反序列化 hashmap、循环遍历 hashmap 并尝试匹配在标头中发送的 JWT。这似乎是很多工作?还有其他方法吗?

如果用户想要注销,则该过程与再次登录非常相似,除了第 4. 点,我将从哈希图中删除 JWT然后保存。

目前我只是将 JWT 令牌存储为密钥并执行简单的 jedis.get(RequestHeader.JWT) 在受保护的 api 端点上。如果有一种查询值而不是键的方法,那么这将是理想的,因为我可以将键存储为 JWT,将 userId 存储为值。

像这样:

final String token = authHeader.substring(7); // The part after "Bearer "
 try 
      final Claims claims = Jwts.parser().setSigningKey("$secret")
           .parseClaimsJws(token).getBody();
            request.setAttribute("claims", claims);
            request.setAttribute("token", token);
  catch (final SignatureException e)   throw new ServletException("Invalid token."); 

if (redisClient.get(token) == null) throw new ServletException("Invalid or expired token.");

【问题讨论】:

你要在每个 API 中发送 userId 和 JWT 吗? 是的@navaltiger 【参考方案1】:

您可以按照以下步骤将JWT 用于您的 API:

    用户登录 -> 创建过期的 JWT。 用户注销-> 在 Redis 中保存无效令牌。

    当用户调用 api -> 你检查 JWT:

    如果有效令牌而不是 Redis 无效令牌 => 身份验证 如果不是无效的或属于 Redis 的无效令牌 => 未认证

    如果要获取登录用户,可以在用户登录时将登录用户存储在Redis中。

【讨论】:

如果我没有看错你,保存所有无效令牌是浪费内存。使用TTL 功能足以控制有效和无效令牌,方法是在一定时间内使它们过期(取决于用例和安全级别)。

以上是关于我应该/如何将我的 JWT 令牌存储在 redis 中以便我可以看到当前的用户会话?的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的 JWT 令牌存储在我的状态中?

在 Redis 中存储 JWT 令牌的标准做法是啥?

如何在spring oauth使用redis令牌存储中获取jwt令牌的解码详细信息

如何将我的 JWT 令牌附加到每个 axios 调用?

在哪里存储 JWT 令牌?

存储JWT令牌的位置?