Can JJWT invalidate tokens on the server-side?

I'm new to JWT and was wondering if it is possible to invalidate/void JWTs on the server-side when a user signs out of an application (I'm also wondering if it even makes sense to do so!). Idea is:

  1. User clicks a sign out link in their app
  2. App makes a call to POST https://api.myapp.example.com/auth/invalidate
  3. The JWT (which is an authorization/bearer token in the HTTP request header) is somehow invalidated
  4. Now, no one can ever use that JWT again

I'm not sure if this is an unorthodox approach to signout logic or not, or whether its acceptable to just let the JWT linger as valid, even after the user signs out (I guess I could shorten the life of the JWT expiry to, say, 60 mins or something).

So again: wondering if its possible to do this kind of "invalidation" using JJWT (and if so, how?!) as well as whether it even makes sense to do this (and if not, what does a typical signout flow look like?!). Thanks!

3 answers

  • answered 2018-07-10 19:17 chrylis

    This is one of the core downsides of JWT--they're self-contained tokens, which means there's no inherent way to invalidate them. At most, you could create a token ID (UUID.randomUUID()) and try to maintain a revocation list, but then you're back to needing most of the infrastructure JWT is supposed to free you from.

  • answered 2018-07-10 19:38 benjamin c

    You don't invalidate JWT, JWTs are immutable. Validity of the token depends on expiration time and signed key, in a serious security incident you can change the signed key then already issued tokens will be invalidated. Also you can use blacklist of tokens in the database, but this will cost another trip to database, if you use this the authentication flow won’t be stateless anymore.

    Once user signed out, then the token must be deleted from client side where the token is stored, typically storage of the token is a cookie or the localStorage of browser.

  • answered 2018-07-10 20:15 vtosh

    The other answers are correct in that you normally don't need a sign-out/invalidate endpoint. A user signing out from your application means you just delete his/her token from local storage.

    If you are however still determined to implement a token invalidation endpoint, you could do it by keeping track of a "blacklist" containing the IDs of invalidated tokens:

    • When a user calls the endpoint, you add the token's ID to the blacklist.
    • For every authenticated request you first check if the token's ID is contained in the blacklist and refuse access accordingly.
    • Make sure that old/obsolete blacklist entries are automatically cleaned up and don't eat up your memory.
    • However also make sure that the blacklist's entries' time-to-live is at least as long as the token's validity duration.

    For the implementation, you don't necessarily need a DB, you can use an in-memory self-expiring map like f.i. guava's CacheBuilder or one of the alternatives discussed in this thread.