Skip to content Skip to sidebar Skip to footer

How To Handle Authentication With React-router?

Trying to make certain routes require Authentication. I have this: class App extends Component { render() { const menuClass = `${this.props.contentMenuClass} col-xs-12 col-

Solution 1:

A simple solution would be to make a HOC (High Order Component) that wraps all protected routes.

Depending upon how nested your app is, you may want to utilize local state or redux state.

Working example: https://codesandbox.io/s/5m2690nn6n (this uses local state)

routes/index.js

importReactfrom"react";
import { BrowserRouter, Switch, Route } from"react-router-dom";
importHomefrom"../components/Home";
importPlayersfrom"../components/Players";
importSchedulefrom"../components/Schedule";
importRequireAuthfrom"../components/RequireAuth";

exportdefault () => (
  <BrowserRouter><RequireAuth><Switch><Routeexactpath="/"component={Home} /><Routeexactpath="/players"component={Players} /><Routepath="/schedule"component={Schedule} /></Switch></RequireAuth></BrowserRouter>
);

components/RequireAuth.js

importReact, { Component, Fragment } from"react";
import { withRouter } from"react-router-dom";
importLoginfrom"./Login";
importHeaderfrom"./Header";

classRequireAuthextendsComponent {
  state = { isAuthenticated: false };

  componentDidMount = () => {
    if (!this.state.isAuthenticated) {
      this.props.history.push("/");
    }
  };

  componentDidUpdate = (prevProps, prevState) => {
    if (
      this.props.location.pathname !== prevProps.location.pathname &&
      !this.state.isAuthenticated
    ) {
      this.props.history.push("/");
    }
  };

  isAuthed = () =>this.setState({ isAuthenticated: true });

  unAuth = () =>this.setState({ isAuthenticated: false });

  render = () =>
    !this.state.isAuthenticated ? (
      <LoginisAuthed={this.isAuthed} />
    ) : (
      <Fragment><HeaderunAuth={this.unAuth} />
        {this.props.children}
      </Fragment>
    );
}

exportdefaultwithRouter(RequireAuth);

Or, instead of wrapping routes, you can create a protected component that houses protected routes.

Working example: https://codesandbox.io/s/yqo75n896x (uses redux instead of local state).

routes/index.js

importReactfrom"react";
import { BrowserRouter, Route, Switch } from"react-router-dom";
import { createStore } from"redux";
import { Provider } from"react-redux";
importHomefrom"../components/Home";
importHeaderfrom"../containers/Header";
importInfofrom"../components/Info";
importSponsorsfrom"../components/Sponsors";
importSigninfrom"../containers/Signin";
importRequireAuthfrom"../containers/RequireAuth";
import rootReducer from"../reducers";

const store = createStore(rootReducer);

exportdefault () => (
  <Providerstore={store}><BrowserRouter><div><Header /><Switch><Routeexactpath="/"component={Home} /><Routepath="/info"component={Info} /><Routepath="/sponsors"component={Sponsors} /><Routepath="/protected"component={RequireAuth} /><Routepath="/signin"component={Signin} /></Switch></div></BrowserRouter></Provider>
);

containers/RequireAuth.js

importReactfrom"react";
import { Route, Redirect } from"react-router-dom";
import { connect } from"react-redux";
importShowPlayerRosterfrom"../components/ShowPlayerRoster";
importShowPlayerStatsfrom"../components/ShowPlayerStats";
importSchedulefrom"../components/Schedule";

constRequireAuth = ({ match: { path }, isAuthenticated }) =>
  !isAuthenticated ? (
    <Redirectto="/signin" />
  ) : (
    <div><Routeexactpath={`${path}/roster`} component={ShowPlayerRoster} /><Routepath={`${path}/roster/:id`} component={ShowPlayerStats} /><Routepath={`${path}/schedule`} component={Schedule} /></div>
  );

exportdefaultconnect(state => ({
  isAuthenticated: state.auth.isAuthenticated
}))(RequireAuth);

You can even get more modular by creating a wrapper function. You would be able to pick and choose any route by simply wrapping over the component. I don't have a codebox example, but it would be similar to this setup.

For example: <Route path="/blog" component={RequireAuth(Blog)} />

Solution 2:

You spelled Autheenticated wrong.

Also, this is an assumption because you only provided the stack trace and not the above error, which probably says AuthenticationService.IsAutheenticated is not a function.

Post a Comment for "How To Handle Authentication With React-router?"