使用JWT令牌获取在线用户



我想创建一个返回在线用户列表的服务。用户使用JWT令牌登录——但我不确定如何获取在线用户——或者/并返回用户列表,但指示他们是否在线。

我是否必须在mongodb中存储已登录/注销的会话令牌/电子邮件-如果它们不注销怎么办?

我当前的代码是这样的

@CrossOrigin
@GetMapping("/api/getActiveUsers")
public ResponseEntity<Object> activeUser(HttpServletRequest request) {
TokenManagement user = new TokenManagement();
try {
// return the user authenticate
HttpSession session = request.getSession(true);
List<Object> userListHttp = (List<Object>) Arrays.asList(session.getAttribute("user"));
// alternative way for get user logged
List<String> userList = getUsersFromSessionRegistry();
return ResponseEntity.ok().body(userListHttp); 
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}

public List<String> getUsersFromSessionRegistry() {
return sessionRegistry.getAllPrincipals()
.stream()
.filter((u) -> !sessionRegistry.getAllSessions(u, false)
.isEmpty())
.map(o -> {
if (o instanceof Person) {
return ((Person) o).getEmail();
} else {
return o.toString();
}
}).collect(Collectors.toList());
}

您可以从即将到期的JWT中提取用户。

然后你可以使用缓存(例如考虑Redis)将用户存储在记录上,当JWT过期时自动过期。

如果用户显式登出,只需从缓存中删除该用户。

所以要计算用户,只需要计算缓存中的项。

如果客户端出现错误并且在没有显式注销的情况下断开连接,那么将在登录的用户号上显示错误,这不会授予您这样的权限。,但由于缓存

的过期,它会得到缓解。我建议使用Redis而不是本地缓存,因为如果你在一个微服务环境中有多个微服务实例,它也会起作用,因为记录的用户存储在所有微服务实例共同的外部缓存中


您可以使用Filter来拦截所有HTTP传入请求:

过滤器是一个对象,它对对资源(servlet或静态内容)的请求或对来自资源的响应执行过滤任务,或对两者都执行过滤任务。

public class SessionFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
HttpServletRequest req = (HttpServletRequest) request;
String bearer = req.getHeader("authorization");
String jwt = bearer.substring(7); // Remove Beared at the beginning 
String username = extractUsername(jwt);
Date expiringDate = extractExpiring(jwt);
insertInCache(username, expiringDate);
chain.doFilter(request, response);
}
...
private String extractUsername(String jwt) {
// Use libraries to extract the username from the jwt 
}
private Date extractExpiring(String jwt) {
// Use libraries to extract the expiring from the jwt 
}
private void insertInCache(String username, Date expiringDate) {
// Insert username in the cache with automatic expiring
}

}

此代码将拦截所有传入请求,提取令牌,解析它并将用户插入缓存中。考虑使用任何java库从JWT中提取信息,以创建extractUsername和extractexpired方法。

这段代码只是一个基本的程序代码。您需要使用以下语句完成:

  • 管理未认证的请求
  • 管理显式退出(在控制器中)
  • 添加一个方法来计数用户查询缓存(在控制器中)

最新更新