Start Redux/React Polling after Login - reactjs

I'm new to Redux, this is a best practice question.
I have a server that i'm logging my app into, on a successful Login i'm returned a tokenId and an expiry time for that token.
tokenId is attached to subsequent API requests to ensure my sessions is valid. Before the expiry time is exceeded i'm required to send a request which generate a new tokenId.
Where is the best place to poll token regeneration? I believe calling an Action from a Reducer is against best practices.

Related

How to design React signIn proccess with NodeJS and sessions stored in cookies?

I have React signIn form and sessions mechanism implemented in NodeJs. In React I have protected routes only for authenticated users.
How should I check if user is authenticated. I have two ideas:
If user sign in for the fisrt time I can save this information in LocalStorage and then evrytime just check localStorage.
Send request to NodeJS server every time to check if user is authenticated.
Do you have any other ideas? Which solution should I pick?
I tried both options and second one is more UI unfriendly becasue I have to run loading state evrytime I am waiting for auth response. On the other hand, first option has also disadvantege, because I am based on token in LocalStorage which can be malicious.
Every time a request is made to an endpoint that requires authentication, the request should contain proof that they are who they claim to be.
The classic way to do this is by storing some sort of "Session ID" in a cookie or localStorage (client side), that you send along with every request.
Using a "Token" (e.g: JWT) instead of a "Session ID" is another popular way to handle authentication.
Check out this article for more information about both: https://dzone.com/articles/cookies-vs-tokens-the-definitive-guide
To return to your question, I'm not sure what you're worried about in regards to a "malicious Token in localStorage" (Or do you mean localStorage can be malicious?). But for a secure application you have to either:
Store something client-side
Require your user to provide credentials (username + password) for every request

OAuth access_token refresh techniques

I'm implementing OAuth in my React / Redux ( Or other Flux based state management ) application, And i'm struggling to find good information on "pro's vs cons" of various access_token extension methods.
1) Intercept 401 responses
One option would be to intercept API requests (E.g using "fetch-intercept" package) and detect any 401 HTTP code responses.
In the case we 401 we build logic to retrieve a new access_token, and then replay the previous request.
Replay could be handled via dispatching an INVALID_TOKEN action in the 401 handler, catching these through middle-ware, Which would then replay the action before the INVALID_TOKEN action occurred.
Pros
Full visibility of auth failure related actions are visible ( Therefore we could replay auth related bugs using time travel debugging )
2) Detecting out of date access_token at time of API call
Another method would be at the time of sending any request, decode our access_token and check if we need to refresh it soon ( And if so do so ).
Again some sort of middle-ware would be the best option for this solution. We could intercept all actions and before dispatching it first check we have a valid access_token.
Pros
Doesn't need to hit the server just to receive a 401 response we could have instead preempted it
Cons
More complicated logic to queue the requests whilst we're refreshing a token, before finally replaying them once it's been correctly refreshed
3) Polling method
Upon login, see how long it is until the token expires and set a timeout to refresh the access_token just before then
Pros
Simplest option ( Especially when retrofitting an app with lost of existing request logic )
Any additional options or pro's vs cons for each method would be appreciated, so perhaps I can create an exhaustive list here for those starting out

Best practices for refreshing JWT in SPA?

Hi I'm developing a React app that communicates with an Express API. I'm trying to implement JWT authentication but I don't know what should happen when the jwt expires. It not seems very user friendly if the user is logged out when the token expires.
Should I use refresh tokens? As it says in the node-jsonwebtoken package documentation (jsonwebtoken). This may not be the best approach.
Should I create a new jwt in every request to the server? If the user reads an article for a long time without doing any request, he is going to be logged out.
Maybe I'm wrong and the best practice is using a big expiration time and let the user be logged out. If this is the case what would be a reasonable time?
Thanks!
A pattern commonly used along with refresh tokens is to follow a workflow along the lines of:
Some API call / resource returns with a 401, alerting that the token has expired, this sometimes is accompanied by a reason, e.g. Expired token, invalid token
Create a reference to the API call that failed, to retry later
Attempt to refresh the token with the refresh_token
If the refresh works, go ahead and perform the queued API call again
If the refresh fails, the user will need to log in again
You can also use the above approach to queue multiple failed requests, in the event that multiple calls fails whilst a refresh is taking place.
Coupled with a decent expiry time, which really depends on your application, this has proven to be a robust solution in the past for me.
An alternative approach would be to implement a 'heartbeat' API call that updates the user's token periodically whilst they are on the site, however this may come with side effects that may not be desired.

React-Redux Strategies for Refreshing Cognito IdToken

I'm using the following combination of packages:
react
redux
react-cognito
react-router (v4)
redux-saga
(and I'll disclaim that I'm pretty new with all of these)
Currently I have a PrivateRoute component which will check (and refresh if necessary) an expired IdToken on route changes. This works well.
My problem is if the browser is open past token expiry to a PrivateRoute which is polling my API and sending along the IdToken in its 'Authorization' header. The API will start returning 401.
Options I've Thought of:
Act on API Error
I could catch the 401 error and dispatch an action to refresh the token, but
if there is any issue refreshing the token I wind up in an infinite loop hammering AWS, so need some logic to catch and prevent this. Perhaps redirect to login route if refresh fails?
I then need to add complexity to all my private API calls throughout my app to have this logic, and re-do the requested API call upon successful refresh.
Pre-empt API Error
To me it makes more sense to separate API calls and keeping the auth token valid. Considering react-cognito stores the token expiry time in cognito.user.signInUserSession.idToken.payload.exp, maybe it is possible to pre-empt the API call and expiry.
How to best do this though? At login a refresh action could be 'scheduled' using setTimeout for (currentTime - expiryTime - someBuffer) seconds in the future.
I'm assuming (haven't verified) AWS will let you refresh an IdToken before it expires. I don't want to wait until afterwards else some API calls may have already failed.
are there concerns with using setTimeout with a timeout that may be up to 1 hour long?
Alternatively I could set something up to poll cognito.user.signInUserSession.idToken.payload.exp frequently to detect and refresh an almost-expired token?
Any suggestions?

Managing a JWT Session with React?

I have a very general question concerning a JWT Session.
Whenever I fetch something from the database I need to sent the token along to autentificate. In case the token is expired, I need to check if the token is still valid. How do I manage this in a simple fashion? So that the user is directed to a login page whenever the token is invalid?
Do I always have to dispatch my intended action (e. g. a GET req. to fetch news articles) and dispatch a SECOND action everytime which deletes the token from SessionStorage if it is not valid and redirects the user to the login screen? This seems like a bad solutions because it somplicates literally every action?
So my basic question is, how do I manage a JWT session in a good way?
JWT token usually comes with the expiration time, store it in local storage and refresh it when needed.
sample code : https://auth0.com/docs/quickstart/spa/vanillajs/05-token-renewal

Resources