5

I'm trying to write Authentication checking for my DashBoard. But the function itself is not getting called. Can anyone give me some solution for this? I'm developing in ReactJs.

This is the Route part :

 <Router>
            <div>
              <Route exact path={"/"} component={Home} />
              <Route path={"/SignUp"} component={SignUp} />
              <Route path={"/SignIn"} component={SignIn} />
              <Route path={"/Dashboard"} component={Dashboard} onEnter={this.requireAuth} />
            </div>
          </Router>

This is the function :

  requireAuth (nextState, replace) {
    console.log("?????????????",this.state.getToken);
    if(!this.state.getToken) {
      replace({pathname: '/'});
    }
  }
Riya Kapuria
  • 9,170
  • 7
  • 18
  • 32

1 Answers1

15

In react-router v4, you can make use of render prop to Route along with the lifecycle methods to replace the onEnter functionality existing in react-router v3.

See this answer for more details:

onEnter prop in react-router v4

However since all you want to do is authentication in the onEnter prop, you could easily create a HOC that does that

const RequireAuth = (Component) => { 

    return class App extends Component { 
    
        componentWillMount() { 
            const getToken = localStorage.getItem('token'); 
            if(!getToken) { 
               this.props.history.replace({pathname: '/'}); 
            } 
        } 
        render() { 
           return <Component {...this.props} /> 
        }
    } 

} 

export { RequireAuth }

and use it like

<Route path={"/Dashboard"} component={RequireAuth(Dashboard)}/>

Edit: In case you need to make a network call to find if the use if authenticated of not, you would write the HOC like

 const RequireAuth = (Component) => { 

    return class App extends Component { 
        state = {
            isAuthenticated: false,
            isLoading: true
        }
    
        componentDidMount() {
            AuthCall().then(() => {
                this.setState({isAuthenticated: true, isLoading: false});
            }).catch(() => {
                this.setState({isLoading: false});
            })
        } 
        render() { 
           const { isAuthenticated, isLoading } = this.state;
           if(isLoading) {
               return <div>Loading...</div>
           }
           if(!isAuthenticated) {
               return <Redirect to="/login" />
           }
           return <Component {...this.props} /> 
        }
    } 

} 

export { RequireAuth }

Update:

In addition to the HOC, you can also go for the PrivateRoute component like

const PrivateRoute = ({component: Component, isAuthenticated, isLoading, ...rest }) => { 
           if(isLoading) {
               return <div>Loading...</div>
           }
           if(!isAuthenticated) {
               return <Redirect to="/login" />
           }
           return <Component {...this.props} /> 
        }
    } 
} 

 export { PrivateRoute };

and you can use it like

  class App extends Component { 
        state = {
            isAuthenticated: false,
            isLoading: true
        }
    
        componentDidMount() {
            AuthCall().then(() => {
                this.setState({isAuthenticated: true, isLoading: false});
            }).catch(() => {
                this.setState({isLoading: false});
            })
        } 
        render() { 
           <Router>
              <div>
                  <Route exact path={"/"} component={Home} />
                  <Route path={"/SignUp"} component={SignUp} />
                  <Route path={"/SignIn"} component={SignIn} />
                  <PrivateRoute path={"/Dashboard"} component={Dashboard} isAuthenticated={this.state.isAuthenticated} isLoading={this.isLoading}/>
               </div>
           </Router>
        }
    } 

   
HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • 3
    Could someone not just edit the react state via react dev tools to make `isAuthenticated: true` and `isLoading: false`? Then they would have access to the protected route – JL9 Jul 21 '18 at 21:03
  • 1
    @JL9 if they do this they would get to the view, but if they send an invalid request to the backend the server should respond with 401 and the ui would then redirect to login – Len Joseph Oct 07 '20 at 04:12