Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should/could I store my JWT tokens in redis so that I can see current user sessions?

I'm using Java with Spring to build a rest api along with a couple of other services.

The main functionality being the creation/login of users. I know that there isn't a query language in redis which is why I'm posting the question here! Is there some sort of library in Java that allows us to query against Redis? In my case to get all the current jwt tokens (sessions) that are assigned to a user (userId)?

I thought of an implementation by myself but am thinking it's a bit over the top and clunky?

  1. I'd use the userId as the key
  2. I'd then store a hashmap of JWT tokens inside the value section.

Example

  1. User logs in
  2. We create JWT
  3. We create a hashmap and then add the JWT
  4. We'd then assign the hashmap as a byte array to a redis key (userId)
  5. We'd save the redis key+value

If the same user logs in, I'd have to go through again and do the following:

  1. Create JWT
  2. Search for existing redis keys with the userId
  3. We'd then cast the found value to our initial JWT object
  4. We then add another JWT object to the hashmap
  5. Save the key+value

This means on each request to protected api endpoints I'd have to search by userId, deserialise the hashmap, loop through the hashmap and try match the JWT that was sent in the header. This seems like a lot of work? Is there another way of doing this?

If a user wanted to log out the process would be very similar to logging in again, except for point 4., I'd delete the JWT from the hashmap and then save it.

At the moment I'm just storing the JWT token as the key and doing a simple jedis.get(RequestHeader.JWT) on protected api endpoints. If there was a way of querying against the value and not the key, then this would be ideal, as I could just store the key as the JWT and the userId as the value.

Like so:

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.");
like image 723
James111 Avatar asked Aug 10 '16 04:08

James111


1 Answers

You can use JWT for your API by following this steps:

  1. User login -> create JWT with expire.
  2. User logout-> save invalid token in Redis.
  3. When user call api -> you check JWT:

    • If valid token and not in Redis invalid tokens => authentication
    • If not invalid or belong to Redis invalid tokens => unauthentication
  4. If you want to get logged users, you can store logged user in Redis when the user login.

like image 56
Quoc Dat Avatar answered Sep 22 '22 16:09

Quoc Dat