Next.js+Redux authentication and redirect - react-redux

I'm starting to build a next.js application and i'm using redux.
I read a lot about authentication in next.js and specifically with redux.
Let's say I have a /login page and a /private page.
And my redux store contains isAuthenticated state.
So, as i see it, i need to think of the following scenarios:
When navigating to /private through the address bar (SSR) , i should redirect to /login.
When already in /private and the isAuthenticated changed to false.
After logging in successfully in /login, update isAuthenticated state and redirect to /private page.
Did i miss some important possible scenario (UX and security wise)?
Regarding those cases, I have a few questions for the experts here:
For scenario number 1, i implemented an authentication check in getinitialprops (only when ctx.req is not null). If the user is not authenticated, i redirect him with 302 response to the /login page. Is that ok?
About scenario number 2, where should i implement this logic? What is the best practice? I can think of implement the check in getinitialprops, in render() function, in componentDidUpdate...
Should i redirect after calling the redux action (authenticate), or in the redux action?
Should i fire the login request from within the redux action or in the handle function in component, and on success call the redux action.
When redirecting, should i use Router.push or Router.replace?
Please help me to understand the best practice once and for all.

This is based on experience:
For scenario number 1, i implemented an authentication check in getinitialprops (only when ctx.req is not null). If the user is not authenticated, i redirect him with 302 response to the /login page. Is that ok?
Yes, this is okay. It does what it needs to do.
About scenario number 2, where should i implement this logic? What is the best practice? I can think of implement the check in getinitialprops, in render() function, in componentDidUpdate...
Definitely getInitialProps. What we did is we made a helper that can be used by both SSR and CSR components. What the helper does is it accesses the Cookies for both instances, that way, the auth state is consistent. There could be better ways but this is how we implemented it.
Should i redirect after calling the redux action (authenticate), or in the redux action?
Depends on your team's protocol. For us, all side effects such as redirections, are allowed to be done inside the Redux Sagas.
Should i fire the login request from within the redux action or in the handle function in component, and on success call the redux action.
I would suggest using Sagas as it is much more cleaner and gives you another layer to keep all your sideeffects in. But in your case, I would suggest keeping the actions clean and just do what it needs to do: change the state.
When redirecting, should i use Router.push or Router.replace?
I would suggest Router.push. Using replace would overwrite the top of the route stack and that may lead to undesirable effects when hitting back or what not. This would depend on your requirements should it be concerned about what happens when you hit back.
Don't overcomplicate things. Make it work and find better ways to do it after you actually make things work.

Related

Dynamically Update Page in Application Requiring Authentication Via Azure AD

I am curious if anyone has a solution to this unique situation as I have a solution currently, though I feel it is not the most optimal.
The Situation.
I have built an MVC style web application that talks to a web API through http (authenticating via JWT). My web application is secured by appending authorization to its view controllers and redirecting to a Microsoft login endpoint - then directing back to the view where whichever given controller/function handles the request, connects to the API, appends data to the view, etc.
Preferably I would like to use JQuery/Ajax to submit http requests client-side and update a given view with whatever data the user may wish to see relative to the webpage they're on. This way I could control exactly what the user should see landing on the page any which way and submitting requests from web app to API. Also would enable better continuity between requests as there isn't actually a full refresh of the view. All in all it is my line of thought that this execution would lead to a nice user experience.
The Problem.
So the big issue that I have had to circumvent is CORS Policy. I initially attempted to use JS just as I said above but requests would be redirected to the login endpoint and blocked due to there being no CORS header appended to the request.
'So include a policy in your application and append an authorized header to your Ajax outgoing request' you might say, well... you cannot override CORS security around Microsoft's login endpoint.
My Solution.
What I have done simply instead is create HTML Forms around fields the user would pick and chose to specify what data they wanted from the API. Then carry over input data to the returned view via 'ViewData'
and using razor pages of course I can actually initialize JS variables via C# input.
Side Note
I use JS to transform the API data into graphs for the user to see. I am doing this with a JavaScript Library.
My Question to you.
This all leads me to ask then, is there a way to dynamically update a view without using JS? I require a method that can hit the login redirect without being blocked because the request initiated client-side.
Every solution I am aware in some way, shape, or form utilizes JS to make the request. So I am at a loss for how to truly get the functionality I am after without having my requests get blocked due to CORS Policy.
Thanks in advance y'all.

Sending authenticated ajax from another domain

Maybe this is not possible...
I have one site, we'll call it club.com
And I have another site called store.com
I have control of both domains. club.com is powered by a Django project, and store.com is a shopify site.
If you're a member of club.com, you get a discount on store.com
We want to do it so that integration is seamless. No need to enter your club.com credentials to store.com, we want the page to do that for you.
How do I implement this?
I already tried simply putting an ajax call on store.com pointing to club.com, and it seems to work with one exception: The browser is not sending the proper cookies along with the request, so when club.com gets this ajax request it can't authenticate it.
You should consider OAuth2 to achieve what you need.

Angular get user object on full page refresh with jwt

What is a proper way (best code organization) to get user object from JWT in storage on full page refresh (it requires new ajax request) ?
How can I perform an ajax request before my angular app's routing start?
Adding an extra request in resolve part on every route is bad (DRY). How I can simplify that?
Is an abstract view (using UI router) with resolve best solution?
It is a good practice to use ajax with jwt for user experience.
you can set your user object to $rootscope once then use in any route.
using resolve with ui-router is perfect way for your situation as i think .

AJAX login redirecting to returned URL (security)

I'm working on AJAX login form. On submit it sends login data to back-end. If there is a problem with login, appropriate response is returned. When login data valid, back-end creates a session for user and sends back a URL where user should be redirected. I want to return URL, because it changes depending on multiple user settings (language, personal/business, etc.).
Am I overlooking any security issues with this approach? Is it possible for attacker to redirect user to malicious website when browser trusts URL returned from AJAX call?
No, that's a pretty standard method for handling login via an asynchronous handler (assuming that you're doing this over HTTPS, if not, all bets are off).
And yes, it is possible for an attacker to redirect a user, if you allow the attacker to set where the redirect goes.
So that means that you should validate any user-inputted (and hence potentially attacker set) URLs that you're going to redirect to make sure they are safe. Basically make sure the URL is on your domain, and make sure that it's a valid URL. You can go deeper (check for XSS style attacks, etc), but you usually shouldn't have to as long as you're practicing good security practices in the rest of the application.
But then again, that's just basic application security Filter-In, Escape-Out. So filter the inputted URL, and you should be fine...

Ajax, PHP and Security?

My question is that suppose, in my web app, I use ajax to call upon methods on the server side, isn't it creating a security hole in the app? Like, say I have an option for the user to deactivate the account, which can be done by clicking a button. This is done via Ajax.
So, can't a hacker send a request to the server to deactivate the account instead of the user?
HELP!!!
My question is that suppose, in my web app, I use ajax to call upon methods on the server side, isn't it creating a security hole in the app?
From a security perspective, there is no difference between an HTTP request that involves JavaScript and one which doesn't (e.g. that uses a regular form, or is handcrafted).
… but you can't call methods from the client, you can only make requests to URIs. The server might cause a method to be called based on receiving a request to a specific URI.
So, can't a hacker send a request to the server to deactivate the account instead of the user?
They could, which is why you need (trustworthy) authentication / authorisation and CSRF protection (just like you would for a request to disable an account that didn't involve Ajax).
This is not a problem with AJAX alone, but with any arbitrary HTTP request that wants to authenticate/maintain a session. The user needs to be authenticated in some way in order to make requests, this is usually done with cookies. Using AJAX does not make the matter any worse though because it is still a HTTP request.
Authentication alone is not enough though, someone could always be listening on the wire and capture the authentication cookie, and thus get hold of the session - "become you". The only solution here is to encrypt the connection on a lower OSI layer level (using SSL/TLS). This is why you should always use SSL when it comes to authentication.
This Ruby on Rails security guide has a great explanation on how to deal with AJAX requests that could be potentially exploited. It's not specific to RoR so the concepts can apply to any platform.
One way to reduce the risk of cross site requests is to use POST for actions that modify or delete data.

Resources