Store JWT/authorization on the Client/Server side of application [JavaScript] - node.js

Right now I am using a JWT token to validate the user and on the client side I store it in cookies. On the server side, I just generate this token and send it to the client side.
As I have seen, there are several approaches where server side tokens / authorization are stored in redis. I don't understand why I would use this. Can you provide me with some use cases for this? And maybe I should store the client side token somewhere else?

Storing JWT on the server with Redis gives you more control over how authentication/authorization works on your app.
Consider the logout process, ideally, it should invalidate a token, but JWT doesn't really give you an easy way to revoke a token.
The best bet is to have it stored somewhere (Redis) and when a logout request is received, the saved token is deleted.
Redis is relatively fast, because of its cache feature, which basically allows you to save/retrieve the token in memory, and it also provides some cool features, one of which is to expire/self-delete a saved token after a set time.

Related

Is Safe JWT Store in Req. Session?

i have a question about MERN Stack (Mysql,Express,React,Node). I confused about storing Jwt token (in Cookies,Localstorage or as session in request).
What iam asking is Is Safe Storing JWT On Request Session ?
Can someone explain how to store token in Single Page App ?
Thanks Anyway ...
When we do a successful login we get an access token. In this case, it is a JWT token. When we get this we need to keep it somewhere to use it for the future use of the user. We normally store that in LocalStorage. You can find more info about LocalStorage here. We also can use SessioStorage, Cookies as well. But Cookies only can contain 4KB of data and SessionStorage will go away when the browser is closed. That is the reason for me to go with LocalStorage. But you can choose it depending on your application requirement.
When sending a request with a token, I use the Authorization header.
It's safe to store JWT cookie at the client and even more in this day and age it necessary for scalability.
What should you use?
Session - This is the "old" way of doing things and no in use anymore. The session saves a state on the API server and that is a bad thing for scaling.
Localstorage - A good choice for mobile and web applications. The idea here is that you as the client developer are responsible for keeping track of JWT (save it on login, remove it on logout)
JWT-Cookie - is the best for ONLY web application. It's the same idea of Localstorage but now the server is responsible for setting and removing the JWT from the client using the Set-Cookie header.
Note: You can implement both Localstorage and JWT-Cookie side by side.

getstream chat: Using a new JWT token for each server side request

Following the GetStream chat API docs I've been wondering if there's any disadvantage in sending a newly signed token with each server-side API request.
That way my server will remain stateless and will allow me to generate very short lived tokens.
Generating a new token for server-side for each request doesn't make much sense because server-side has already full access since using API secret.
If you have multiple API keys, then having the same number of tokens with their respective secrets sounds fair. Here, we assume this is a secure environment because it uses secret to do anything on your account.
If you check server-size SDKs (Go, Python, etc), when you create a client, they actually generate your token and cache it.
However, client side is a different story. JWT is stateless but probably your app needs (session) state management and expiration should be done (logout for example). In this case, 15 mins to expire a token and refresh token under the hood is a pretty common practice.
Short JWT expiration
pros:
no need for central storage (blacklisting for logout, password change, etc)
more secure (changed more frequently even if stolen)
cons:
more processing time/resource are spent to sign a new token (cryptography is slow)
more network requests for refresh
bad user experience if token isn't saved, instead kept in memory (needs login and security might be a problem on saving since token could be stolen otherwise)

How to handle refresh token on react spa?

I have two servers. One for Hasura GraphQL api which queries the db and provides app data. Another is a node server for authentication. These two servers are not on the same domain.
I have a react spa client. When a user logs in, the node server validates the credentials with the hasura graphql endpoint and provides a jwt token and refresh token to the client. The refresh token is sent via httpOnly cookie as the react client and node server are on the same domain.
Now when the jwt token expires, I want to silently refresh the jwt token using the refresh token which is sent automatically as a cookie to the node server. How would I implement this?
One way that I can think of is, on the client side I decode the jwt and if it's expired I send a request to the refresh token endpoint on the node server and get a new jwt token before sending any request to the hasura graphql server which needs the access token sent as an authorization header. This means I would have to do this check before every graphql request. Is this the optimized way or are there any other way to silently refresh the token given my application architecture?
Let's use deduction. Obviously, you can either check the expiration time at the client-side or let Hasura do that for you (and return an error whenever the token's expired).
If you check it on the client side, you will lose some milliseconds before each call to Hasura but will save a single Hasura round-trip whenever you detect an expired token. I would take a base64 decode of a JWT payload over an HTTP call anytime, so IMO there is no a better way to handle JWT auto-refresh, if that's your only concern.
OT but IMHO JWT is not an excellent solution when it comes to things like expiration, blacklisting, etc.. E.g.:
what if at some point you decide that you need to check if the account is suspended? You'd then have to start making calls to your auth server before each call to Hasura;
even if you deal with that, what if you decide to perform (for whatever reason) an auto-login on app-load? Or an auto-refresh at an interval? It's easy to do that with a single tab, but things will go south pretty quick once your user has two or more tabs of your application open at the same time.
I suspect that in many such cases people end up implementing sort-of sessions, only without cookies, which is a bit like reinventing the wheel.
May I suggest looking into Hasura's webhook auth system instead, if you find yourself going down a similar path in the near future - it might just be the optimal choice.
BTW, such questions might be better suited for the Software Engineering SE.
This blog explains JWT and use cases around it very succinctly, https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
It covers use cases of silent refresh and how to design auth server.

Where to Save Auth Token

I have one issue, where I would need some inputs.
In my current application, using Node,Express I have a auth token which is generated by third party post login. I need to save this token on Node layer, as I cannot expose this token on client side.
Is there a better way to save this token on Node layer for each user specific once user gets logged in into the system and invalidate if user logout.
Please note that, there is no authentication done on node layer, it all verifies on some third party API's and that API generates a token.
So my question:
How I can save this token on node level.
Is there any way available by which I can save token for each user,Currently I am thinking to use Redis as it is just key value pair.
If I compare Mongo Vs Redis, which will be a better option?
Is there any other way around to solve such scenarios?
For example If I will save this on client cookie, how I can make
this token more secured, so that client cannot read this token.
This is not a complete answer since I do not know whether there is a secure approach to save a token on a cookie. I think that using Redis database is the way to go for its greater performance compared to MongoDb since you would be storing key value pairs as you stated.

Restful API Authentication and Session management for Express.js

I have been researching on RESTful authentication alot, and I still can't get a very clear idea, how can I design my web architecture. I have many questions that are unanswered.
I want my API to be served to mobile and web too and I am using Express v4.
I don't want to use Basic Authentication, as many posts have suggested as a simple way out, or I can use the Passport middleware, but I want to use token based authentication or something similar or better,and I want to make my authentication, so I could understand better, but I am not sure how can I achieve it.
I will simplify my intended authentication architecture below:
Registration of a new user
Client side
Post username and password to server
(I know if you want to make the connection secured is to use https connection, or else I will expose my credentials, or you got any other options besides https? or else I will need to use the public and private key with timestamp and hash my credentials before sending to server? How can i do this? Is there any other better option?
Server side
Hashed the password using salt cryptography, and stored the hashed password and salt, then generate a token ID and sent to the client, and the token ID is stored in sessions or using the REDIS database?
Isn't that using sessions violates REST again? But, if I don't use sessions, how can I store the token ID and compare it with the client side?
Client side
Since now I have the token ID, how can I store on client side?
Should I use cookie? If yes, will this violate the RESTful? And how can my mobile application store the cookie too?
What other options can I have besides cookie? I can't think of any.
Authorizing API
Client side
Now, I have the token ID, I will place this in the authorization header each time I would like to make a request to the server.
Server side
When a request is received, the server will check the token API, and compare it with the session token, if it is true, request allow else reject
Is this a standard way for Express application authorization?
I am sorry for the lengthy post, but I feel that I should really master the authentication and authorization because it is important. I do hope someone can correct my misconception of REST authentication and answer my questions or suggest me a better way to do it.
Send the user credentials encoded over https
To compare the token at the client side you can either keep it in map or in Redis store corresponding to user id and match it to consider user authenticated. It does not kills the significance of Rest as in Rest as well authorization tokens are sessions only which after expiry
Express does not have any specific or standard method of authorization , it only enables you to use any db in backend to perform authentication and authorization as required by your application
Your solution is the use JWT tokens for your authentication .You can read more about JWT at https://medium.com/dev-bits/a-guide-for-adding-jwt-token-based-authentication-to-your-single-page-nodejs-applications-c403f7cf04f4
With JWT tokens you can have a token base auth system with no sessions UID at cookies , but you have to implement logic to handle tokens that have sign out something like blacklist tokens.

Resources