What is the standard practice to store JWT tokens in Redis? - express

Should I store the JWT token as a key and corresponding user info as value in Redis so that I can fetch info by token if valid
or
should I encode the user data in JWT itself and use Redis only for storing valid tokens?

The all idea of JWT is that won't need to access the DB (or Redis) on every call and the user access data will be encoded in the token.
Saying that, the biggest drawback of JWT it that you can't actively cancel or de-validate tokens, and the only way to do is by checking a black list of tokens on every user call, which kinda miss the purpose of not accessing the DB on every call.
A good compromise, in case you need a way to actively cancel tokens, is to use a fast validation method which for example can be based on Bloom Filter, and for that you might want to use RedisBloom.

Since #Guy Korland has already covered the basic idea of JWTs, I'll comment on the two approaches you have mentioned.
Should I store the JWT token as a key and corresponding user info as
value in Redis so that I can fetch info by token if valid
This approach is not very helpful if all you're trying to lookup from Redis is the user's information. This is because the user information can directly be stored as claims in the payload section of JWT thereby avoiding the call to lookup from Redis. If the claim contains sensitive information, one can always encrypt the JWT token to ensure it's not being accessed by un-intended recipients.
That being said, the downside to not having to hit the cache at all is that you cannot invalidate/refresh the tokens. In general, it's recommended that you do not have long lived tokens as it's a security vulnerability.
should I encode the user data in JWT itself and use Redis only for
storing valid tokens
This is better than the previous option and it works if the user's information is encoded as part of the JWT token. Also, you can store the 'context' of the token as the value in Redis (key being the JWT itself). The 'context' here means the last time the token was used (lastAccessTime), expiry interval, etc. Using this 'context' you can determine whether the session is active/inactive and whether to invalidate the token and provide a fresh token to the client.

Related

Recommended Format for Refresh Token

I am making an application that generates refresh token that implements JWT token authentication, and I am not sure what format should I use to identify the refresh token. Initially, I thought that it should be in JWT token format, but based on my googling, it seems like it is represented in a UUID or hashed format? Just wondering whether I should make it JWT token format, or it does not matter in the case of refresh token?
Thanks in advance for helping to clarify this issue.
From here https://developer.okta.com/docs/guides/refresh-tokens/main/ refresh token response it shows the refresh token format is not in JWT format.
First decide how you want to model this, which might work like this:
User authenticates (and optionally consents)
Create a delegation to represent the user action
Delegation is stored as a database row
Fields include sub, client_id, refresh_token_hash, scopes_issued, claims_issued, issuance time, expiry time
Subsequent token requests are validated against the persisted state
The hash might be the returned to clients, or they may be given a different identifier. It is a pointer to backend state.
You might also need to implement support for refresh token rotation, revocation, auditing of tokens issued and so on. Consider using an authorization server, as described in RFC6749, to handle this stuff for you.

What is the correct way to create and store JWT refresh tokens?

I am currently attempting to implement auth into my API and am puzzled by the concept of refresh tokens. I understand they are for generating new access tokens upon their expiration, however I am unsure as to what payload they are meant to carry and how they are meant to be stored in the DB.
Several sources have implemented refresh tokens using the same payload as the access tokens (i.e a userId). Others have implemented a session system whereby a session object is serialized and checked upon validation.
My main confusion regards the validation and invalidation of refresh tokens. Are refresh tokens meant to be stored in the DB alongside the user, such that you can check that it is valid (and not being reused)? If so, should it be deleted from the DB when a new refresh token is generated? If this is the case, how do you allow for multiple sessions across several clients? It seems wasteful to store all past refresh tokens or session objects in the DB, particularly if the expiration time of the access token is short.
Apologies for the somewhat rambling question. This topic is one I'm struggling to get a grip of so any help would be much appreciated.
First please understand the importance of JWT token , they are meant to verify the integrity of the user i.e. genuine user.
For this purpose access token are generated and verified at each request to check weather the authentic user is making that request and also these token have expiring time based on your requirement and to refresh them refresh token are used. now lets say your token have very short TTL and you make request to refresh your token with each request of refreshing these token your server has to access DB and refresh the token , if you have store serialized object in token then it would add another business logic to deserialize and check for the Userid.
therefore the you should store minimum information in these token access token as well as refresh token , and this refresh token you should store along side user with minimum information.

Is it a good practice to store JWT Tokens in memory

I wrote an asp.net core 3.0 web api where I am using JWT tokens to authenticate a user. Once the user gets token, he/she can use it until it expires.
What I have done is that I have also stored this token in-memory on authentication, to get other minimal details e.g. username, token generated at and "token".
My first question is that is it a good practice? since tokens are stateless and therefore saves server side from the hassle of maintaining it.
My second question is that if it is acceptable to do so, then how do I remove this token information from in-memory once a token expires.
If I am not storing this token in memory, how to extract information like "get a list of all logged-in users".
Yes, it is a good practice to cache the JWT in memory cache like Redis or simple in-memory cache. The newly created tokens are cached in memory with cache eviction time same as token expiration time.
When a request comes in to validate token, its first checked whether it exists in memory cache, if not will be looked in to persistent storage like db.
When the user invalidates token(ie logged out), it should be removed from cache and update the state to invalidated in db.
In a distributed application, its a challenge to maintain the state. For this reason, its better to have separate caching layer backed by redis. In this way, we can maintain the application stateless.
In addition to token expiration time, you may want to add additional check for validation, depends on the content of JWT like (aud claim, signature verification etc).
To retrospect the content of JWT token , you can use tools like below
https://devtoolzone.com/decoder/jwt
Cheers,
Lakshmanan
When you say "in memory", does that mean locally on the client machine or somewhere in the server? I'm going to assume you mean client-side for their use.
I'm currently using JWT myself, so here are my recommendations:
1) Save the tokens in session storage.
2) Just empty the session (or wherever you're storing it).
3) You'll definitely need to store it somewhere if you want to access it. But getting a list of all users sounds like you want the data on the back-end. You can keep track of that on a back-end server, but usually these tokens are handled and persisted into databases. But even on a back-end server, you can just have a array of Client objects to track which ones are logged in (i.e. which ones have unexpired tokens).
The typical practice involves generating two tokens (auth token and refresh token) and then checking them against a database when the user submits a token for authentication.

JWT access token security considerations

For my project, I'm implementing OAuth2 authentication framework that uses Bearer tokens.
From a quick search, it looks like JWT tokens are the mainstream choice for Bearer tokens today.
If I would use a "dumb" token that doesn't encode any information, I would be storing this token in a database, alongside all the related parameters (token's user, issue date, expiration date, etc.).
From JWT's documentation I understood that I can avoid this overhead by implementing this flow:
User authenticates with one of the supported methods
Authentication service generates JWT token and encodes the following parameters into it: user id, authentication method used, issue date, expiration date
Authentication service encrypts and then signs the token
The token is sent to the user for subsequent usage
The encryption step is desirable because I wouldn't like to advertise user IDs.
My understanding is that if I use the above method, I can avoid storing the mapping between access tokens and users, and rely entirely on the user ID information provided with the token.
What disturbs me with this approach, is that it looks like I won't have the option to "revoke" access tokens.
In other words - even if access token will become compromised, I won't be able to disable it (unless I know the exact compromised token, which is not the case).
Is this a real concern, or I'm just missing somethig? If this concern is real, how can I work around it?
Access tokens self-contained and are valid as long as the expiration time is valid. There is no specification around invalidating them in the actual spec. Depending on the level of security you need you can adjust the validation time of the tokens, from fewer minutes to hours. Typically the validation time is set for an hour.
If you require higher level of security, you can use Reference tokens. Reference tokens doesn't carry any information, they are plain strings. But, the server (or whoever is consuming these tokens) has to contact the Token Provider to exchange the reference tokens for actual response content. But, these tokens can be revoked if they are compromised.
Please refer to this link for more information and some suggestions on how to overcome some of the downsides of Reference tokens (like back channel communication/ extra round trip to Token Provider). Please let me know if you have any questions.
-Soma.

JWT - per user signing key

In my project there's a requirement to invalidate all jwt tokens of a user when the user changes his password. I was thinking of giving each user a different signing key, and simply reset the key when password is changed. Then I googled around and found Redis is a good place to store those per-user keys. Everything seems to work just fine.
But there one thing I cannot get my head around. Since it has to hit Redis once per request, is it any different than issuing the user an opaque token instead of JWT, and store the token -> JWT payload mapping in Redis?Isn't that defeats the purpose of using JWT?
To invalidate tokens you need to revoke them. OAuth spec also does not require getting secret key from remote server every time you need to validate JWT (as you said it kind of defeats the purpose). The key can be stored locally at resource site.
You have two options here:
1) Introspect the JWT token from resource side against OAuth server every time it validates it. Seems like overkill to me. The best approach is to give short expiration time to JWT token and let the already issued tokens to just expire.
2) Have the resource store the secret key locally and when it fails to validate go and get the key and re-validate it again.
From the point of view of invalidating the token, there's no particular need to store the JWT in Redis - anything that you can check and later invalidate should do the trick.
That said, presumably you're using a JWT for other reasons. For example, it's what the AuthN/Identity service provides. Or perhaps you use it to store claims or other metadata that you validate as part of the AuthN/AuthZ logic. In that case, since it's handy, storing the JWT seems very reasonable.