1

I'm working on a React app where the user needs to be logged-in to do anything. This means that by default every route requires authentication, expect the few pages needed to create an account and so on.

Every article or tutorial I found on the subject (How to implement authenticated routes in React Router 4?) explains how to put all your private pages behind one route (usually "dashboard/"). But I don't want to artificially force my application to have this route structure. When I used to work with AngularJS, I would specify for each route if the user needs to be authenticated or not to access it.

So what's currently the best way to structure your router in react to specify that a few routes are publicly accessible, and the others require authentication and redirect you to the login page if you are not?

jonlop
  • 47
  • 3
  • 5

2 Answers2

1

Essentially you can create a Higher Order Component that use can use to check the auth and do what is necessary... I do something like this for my protected routes:

export const PrivateRoute = ({ component: Component, ...rest }) => {

 return (
    <Route
      {...rest}
      render={(props) =>
        checkAuth(user) === true ? (
          <Component {...props} />
        ) : (
          <Redirect to="/auth/login" />
        )
      }
    />
  );
};

There are several ways to pass in your user object...so I have not put that in there

then in my router I use it as follows:

<PrivateRoute
        exact
        path="/application/version"
        component={AppVersion}
      />
Intellidroid
  • 920
  • 7
  • 15
1

I agree that the solution is with a high order component, here is another example to avoid asking on each route and have a more general way to make private a page

You have a wrapper component: withAuthorization that wraps your component to check if you have access or no to that content.

This is just a quick example, I hope it can helps you

const withAuthorization = Component => {
 return class WithAuthorization extends React.Component {
  constructor(props){
   super(props);
   this.state = {
    auth: false
   }
  }

 async componentDidMount() {
  // ask in your api for the authorization
  // if user has authorization
  this.setState({ auth: true })
 }

render () {
 const { auth } = this.state;
  return (
   {auth ? <Component {...this.props} /> : <Redirect to={`login`} />}
   )
  }
 }
}

export default withAuthorization;

Then when you export your components just have to do it in this way:

withAuthorization(ComponentToExport)
Ruben Saucedo
  • 204
  • 1
  • 10