- generate the salt
- generate the jwt
- use the header base64 string as the key for your database
- store the salt with the header base64 as the key in your database
maybe?just one idea, basically when you are > 100.000 users you barely invalidate a single token. mostly you would kill of your secret which will invalidate any token anyway. but there are numerous ways of doing so.
Edit:
to the poster after me:
actually we never needed to logout a single user. but actually our authorization is not stored in our JWT so if we want to kill a user off, we could just remove any rights from him so he gets a site where he needs to either logout or refresh (which will show him the same site again).
If you need to sign out a user across all logged-in sessions, use a revocation list based on UID, rather than token-id.
Anyone know any good articles I can read on the topic?
Whether it is good to bind the JWT to some combination of user-agent, device cookie, IP address (not recommended) or whatever, is a separate topic...
Each JWT contains two pieces of info: user ID, and salt. This stops the JWT from being a deterministic token that is always the same each time a token is generated for a specific user.
It also allows invalidation. On each request a middleware checks validity of the salt from the JWT. A Redis cache layer here makes this a 1-2ms operation and easy to scale. If you need to invalidate a JWT delete a salt and the respective token is now invalid. Or delete all salts for a user to invalidate all their sessions.
Honestly this use of a JWT is basically just a lightweight session that passes the session ID via a technique that isn't insecure by default like cookies are. Rather than having to opt in to CSRF protection your stuff is hard to CSRF unless your application persists the token insecurely.
Why not just store your sessionID in a cryptographically signed HttpOnly cookie? In most use cases, it'd be less ambiguous, better protected from JS attacks, and equal-or-less vulnerable to CSRF.