我应该/如何将我的 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 中以便我可以看到当前的用户会话?的主要内容,如果未能解决你的问题,请参考以下文章