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

Jam*_*111 5 java session redis jedis jwt

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

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

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

  1. 我会使用userId作为密钥
  2. 那么我存储的HashMapJWT值部分内部的标记。

例子

  1. 用户登录
  2. 我们创建 JWT
  3. 我们创建一个哈希图,然后添加JWT
  4. 然后我们将哈希图作为字节数组分配给 redis 键(userId)
  5. 我们会保存 redis 键+值

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

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

这意味着在对受保护 api 端点的每个请求中,我都必须按 userId 进行搜索,反序列化哈希图,遍历哈希图并尝试匹配在标头中发送的 JWT。这似乎是很多工作?还有另一种方法吗?

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

目前,我只是将JWT令牌存储为密钥,并在受保护的 api 端点上执行简单的jedis.get(RequestHeader.JWT)。如果有一种查询值而不是键的方法,那么这将是理想的,因为我可以将键存储为 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.");
Run Code Online (Sandbox Code Playgroud)

Quo*_*Dat 6

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

  1. 用户登录 -> 使用过期创建 JWT。
  2. 用户注销-> 在 Redis 中保存无效令牌。
  3. 当用户调用 api -> 你检查 JWT:

    • 如果有效令牌且不在 Redis 中无效令牌 => 身份验证
    • 如果不是无效或属于 Redis 无效令牌 => 未认证
  4. 如果要获取登录用户,可以在用户登录时将登录用户存储在Redis中。

  • 如果我没有误读您,保存所有无效令牌是浪费内存。使用 [TTL](https://redis.io/commands/ttl) 功能足以控制有效和无效的令牌,通过在一定时间内使它们过期(取决于用例和安全级别)。 (2认同)