3 ms·
You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it. Exactly. Each JWT I generate has a sa
by NathanKP 10y ago
You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.
Exactly. Each JWT I generate has a salt inside which I store in the DB, and ideally the salt has accompanying data such as the datetime the JWT was generated, the IP address that generated it, etc. Now you can provide an interface that lists "sessions" and allows the invalidation of logged in sessions by deleting the salt from the DB, rendering the JWT invalid.
- mwpmaybe 10y agoI asked this question below, but how do you use the payload to select the correct salt from the database in order to verify the signature before verifying the signature and confirming that the payload is valid?
- merb 10y agoone way would be: - 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).
- mwpmaybe 10y agoInvalidating the site secret is my go-to strategy right now, but I have wondered how to sign out a single user across all their logged-in devices. Anyway, this idea is interesting and would be pretty straightforward to implement. Thanks!
- ponyous 10y agoMaybe you could salt the secret per user and store it in the DB. This would allow users to have a feature like "Logout from all devices". I am not sure how you would query the database to get the salt? JWT as key and salt as value? Or maybe sending userId with each request? Anyone know any good articles I can read on the topic?
- numbsafari 10y agoThe point is to avoid all the database updates. So, I would recommend not going that route. If you need to sign out a user across all logged-in sessions, use a revocation list based on UID, rather than token-id.
- merb 10y agoyep probably the better idea. eventually we combine sessions and JWT Tokens. The session id is kind of a refresh token that refreshes the token if it was expired and the user didn't generate a new token in less than one minute. than it will use the session id will query the database and create a new token if the session is still valid.
- rahkiin 10y agoUsing IP addresses for session (in)validation is pretty useless now that everybody has a mobile device that moves between networks (WiFi at home, WiFi at work, 3G/4G). If you use the website while walking from WiFi to 4G you would lose session.
- NathanKP 10y agoThis is for the use case of: "Something weird happened on my account, so I check sessions and see that someone used my account from across the country. So I log out other sessions."
- tym0 10y agoWait. You have individual salt for each user that you store in your DB?
- NathanKP 10y agoMore than that. A salt for each "session". 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.
- kelson 10y agoSalt is random data used to cryptographically sign or encrypt data. It sounds like your JWT consists of a userID and a sessionID (stored in Redis). 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. https://en.wikipedia.org/wiki/Salt_(cryptography) https://en.wikipedia.org/wiki/Salt_(cryptography)
- sk5t 10y agoThe extra salt is probably unnecessary if you require (and validate) not-before and not-after dates on each token. I couldn't say more without knowing the details of your implementation, but "secret salt" strategies often are a band-aid over some more fundamental problem. 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...