Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REACT - Check authentication before render APP

Tags:

reactjs

Im really stuck here and im not sure why, im kind of new to React so every help i can get would be consider great :D!

I have stored a JWT token inside localstorage when USER is signed in, when we refresh the page i have this function to check if the user is authenticated so we can set the user again.

async checkLoginStatus() {
    console.log('checking');
    const token = localStorage.getItem('sid');
    if (token) {
      let user = await VerifyUser(token);
      if (user) {
        this.setState({
          isLoggedin: true,
          user: user
        });
      } else {
        this.setState({
          isLoggedin: false,
          user: {}
        });
      }
    } else {
      this.setState({
        isLoggedin: false,
        user: {}
      });
    }
  }

  componentDidMount() {
    this.checkLoginStatus();
  }

Here is my routes atm, dont mind the diff of the codes, testing some stuff

<Router>
            <Header handleLogin={this.handleLogin} isLoggedin={this.state.isLoggedin} handleLogout={this.handleLogout} />
            <Switch>
              <Route exact path="/about" component={About} />
              <Route exact path="/portfolio" component={Portfolio} />
              <Route exact path="/" component={ () => <Home user={this.state.user}/> } />
              <PrivateRoute exact path="/user" isLoggedIn={this.state.isLoggedin} component={User} />
            </Switch>
        </Router>

Here is my PrivateRoute

const PrivateRoute = ({ component: Comp, isLoggedIn, path, ...rest }) => {
    return (
      <Route path={path} {...rest} render={props => {
          return isLoggedIn ? (<Comp {...props} />) : (<Redirect to="/" />);
        }}
      />
    );
  };

export default PrivateRoute;

When the user is logged in they can access the Protected page, but when they are logged out they cannot. So that works fine. And when i refresh page anywhere on the site, it checks if we have a token and it login the user, this is not the problem aswell.

The problem is when i am standing on /user <- the protected page, and i refresh page, the user is not logged in, i guess because the function where we check the user to be logged in has not been done yet when we try to render that route. Ive tried changing componentDidMount to componentWillMount with no results.

Any suggestions?

like image 244
Christoffer Bergström Avatar asked Apr 03 '20 09:04

Christoffer Bergström


People also ask

How do you handle 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.


1 Answers

The problem is that initial value of isLoggedIn is falsey, which triggers the redirect (before the state is updated asynchronously):

isLoggedIn ? (<Comp {...props} />) : (<Redirect to="/" />)

What you need is 3 states for 'loading', 'login succes' and 'login fail'.

Example with 2 boolean variables:

state = {
  isLoading: true,
  isLoggedIn: false,
  user: {}
}
...
    this.setState({
      isLoading: false,
      isLoggedIn: false
    })
...
    isLoggedIn ? (<Comp {...props} />) : (isLoading ? 'Loading...' : <Redirect to="/" />)

(the same can be achieved with initial state isLoggedIn: null and condition isLoggedIn === null if you prefer fewer variables)

like image 193
Aprillion Avatar answered Oct 16 '22 16:10

Aprillion