Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing Authentication on Routes with react-router-v4

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: '/'});
    }
  }
like image 602
Riya Kapuria Avatar asked Dec 04 '17 06:12

Riya Kapuria


People also ask

How do you implement authenticated routes in react router?

import { Navigate } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const ProtectedRoute = ({ children }) => { const { user } = useAuth(); if (!user) { // user is not authenticated return <Navigate to="/" />; } return children; }; To redirect the user, we use the <Navigate /> component.

How do I set authentication in react?

There are two main things your React application needs to do to sign on a user: Get an access token from an authentication server. Send the access token to your backend server with each subsequent request.

What is an authenticated route?

Auth routes allow you to specify the routes you want to be authenticated and keep the rest public. By default, all routes are authenticated. For example, you may want to hide a 'staff-only' section of your site behind password authentication.


1 Answers

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>
        }
    } 

   
like image 106
Shubham Khatri Avatar answered Nov 12 '22 14:11

Shubham Khatri