folks. I'm learning how to integrate React with Express using React Router, and I've run into a problem with authenticating users. I'm trying to use a higher order component to conditionally render a protected route based on a user's authorization status.
const ProtectedRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={props => {
if (!AUTHORIZED) {
return <Redirect to="/login" />;
}
return <Component {...props} />;
}}
/>
);
};
The problem I'm having is in the if (!AUTHORIZED)
statement. I'm using Passport to handle authentication on the Express server side, and I have an endpoint set up for retrieving user information and authorization status, but I can't figure out how to get access to that data before the page renders. If I was using a class component instead of a functional component, (learning hooks also), I think I could get the data with the componentWillMount
lifecycle method, but I read that's bad practice. Any ideas on how I could move forward from here would be much appreciated!
***edit*** A couple of things I tried to get this working... I tried adding an authorization module to fetch the data for me.
class Auth {
constructor() {
this.authenticated = false;
}
async isAuthenticated() {
console.log("hitting auth route");
await fetch("/api/auth")
.then(res => res.json())
.then(json => {
if (json.error) {
this.authenticated = false;
}
this.authenticated = true;
});
return this.authenticated;
}
}
export default new Auth();
I import the module and plug auth.authenticated()
in place of the placeholder AUTHORIZED
. This function gets skipped, because it's asynchronous, and the redirect will always occur.
So I need to add await
to auth.authenticated()
. But now I need to have async
further up the chain, so I foolishly add async
in front of props
, as such:
render={async props => {
So now It's trying to render a promise object instead of a component, and we get the error Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
Promises all the way down.