Trying to make routes dependent on logged in user roles - reactjs

I'm trying to come up with a way to update routes in react-router after a user logs in and I know what roles the user has.
I was hoping that there would be an API where I could add appropriate routes after the user logs in but no luck there.
I'm currently thinking that I could use the lazy loading so that I originally load the root Route which has a child for each role, then in the definition of those children could use getChildRoutes to test for the presence of the required role before lazy loading the allowed routes.
Has anyone implemented something like this and have a working/better solution?

Related

How do I make my React App secure? As of now I can login using React DOM Tools, what am I missing?

I am currently learning by doing. So I've created the backend using FeathersJS and am authenticating through the endpoint just fine. When the user gets authenticated I set the 'isLoggedIn' state to true and then pass that along to other components to make sure that the user is logged in so they can access that component.
Now when I see and test it using the REACT DOM Tools, I can see that I can just login by clicking on isLoggedIn and it will give me access to my app bypassing the whole login system.
What is the correct way to create a login setup? Can the isLoggedIn state be hidden somehow? Please help!
I've been looking around for information on how to do this but I haven't found anything that useful yet..
Screenshot
You could make use of session cookies. Or I often find myself using Passport.js. But of course this implys that you have control over the server and database.

ReactJS dynaminc component/routes based on user access

I'm new into ReactJS - I'm trying to implement login system with PHP.
I want to have different type of users - some of them should have access only to some portion of app.
Is there any way to prevent those users from accessing certain routes as /admin ?
What I want is not something as simple function that check's user accessible routes and redirecting -> I would like to HIDE/REMOVE components that user has no access to, so he would download the app containing only /login /info, so he won't even download /admin component in app (won't be able to see the code for it)
You can use Higher-Order Components.
With HOC you can wrap other components.. if user have permissions you can return wrapped component, otherwise return null or redirect user to another route.

Custo Signup Page

Background Information:
I have been following admin-on-rest example to create my custom Admin app. I created a custom component that is pretty much the same as https://github.com/marmelab/admin-on-rest-demo/blob/master/src/Login.js
However I want to provide the functionality for users to signup within the application, so I added a Sign Up button, that we clicked will redirect to domain.com/signup
Problem:
After reading the Authentication docs and trying it out myself, I found that on each route change the event AUTH_CHECK is evaluated. However, in input params I get as resource something I already defined in my <Admin> component. Basically, I need a way to "whitelist" a path and allow users to navigate to that path without them being authenticated.
Questions:
Is there a way to create a custom signup page and whitelist the path "/signup" so that authentication is not checked?
Is this something I need to implement with custom React Router routes, or is it something at the authClient level?
Has anyone tried to add a new signup page, and how did you make it work?

How to handle logged in status using React Router?

I'm a noob, starting my very first project with Node, Express, and React.
I got the authentication working, I have a Component that calls an action, which calls a store (or should), but this is where I get confused. I don't know where to go.
My LoginActions.login makes an api call to login the user, it comes back successfully and stores a cookie with the session ID. After that, how do I tell the UI to go to the dashboard? How do I make the UI KNOW that the user is actually authenticated, and if it's not, kick him out?
Where am I supposed to check for all that? Is it the store? The component itself?
Any help would be greatly appreciated.
You're not really "supposed" to do it in any specific way. React is more of a library than a framework. You can use it however you see fit.
One option would be to use react-router's onEnter function to verify logged in status and user it's replace method to redirect accordingly.
You could also have your components themselves verify logged in status and instead render your login form if not logged in yet.
Or you could even store your login form at a unique uri and handle all of the authentication via the server, using 302 redirects based on logged in status.
Up to you!

react-router auto-login in the onEnter hook

In all the react-router examples for the onEnter hook, the hook is synchronous. In the issues it's recommended to keep it that way. What's the idiomatic way to log someone in while inside a hook?
User-story:
Client has a localStore token
Client navigates directly to example.com/mustBeLoggedIn
Before going to that page, I'd like to check if they have a token, if they do, attempt to gain authorization. If authorized, continue onto route
Should I just use a HOC instead of onEnter?
I currently have it working, but I know it's not recommended, and seems very brittle, for example using an immutable store causes the same issues as this issue: https://github.com/rackt/react-router/issues/2365
There are a number of ways to solve this challenge, but I agree with the recommendation that calls in onEnter should be synchronous. Here are two ways to solve this challenge.
Option 1: Don't Validate the Token on Page Load
It is arguably the case that the browser should not validate the existing token at all. That is, the browser should assume that the token is valid and try to load the route as defined.
On an API call failure response from the server (where the actual authentication and authorization is really occurring), your app can handle the need to re-authenticate any way it chooses: redirect to a login page, present a login dialog, etc.
The advantage of this approach is that it will work across all routes that employ this logic without having to specify the routes that need it individually.
Option 2: Use an HOC (recommended)
As you suspected, an HOC is probably the best way to go. Your router would attempt to render something like this:
<EnsureAuthorized checks={myCheckFunction} Component={MustBeLoggedIn} />
This kind of flexible HOC could optionally run custom authorization checks in addition to the required authentication checks (like user roles), and render the component provided only when the authentication and the checks succeed, and then handle failures in a consistent way (e.g. rendering a login component or redirecting the user to the login page or showing a 403-type message, etc).

Resources