0

I am using React-Router V4 and I want to hand over an 'authenticated' prop to decide wether to send the user to a login page or to the requested page:

PrivateRoute.js

import React from "react";
import {
  Route,
  Redirect,
} from "react-router-dom";
const PrivateRoute = ({ component: Component, authenticated, ...rest }) => (
    <Route
      {...rest}
      render={props =>
        authenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
)
export default PrivateRoute;

My App.js looks like this:

class App extends Component {

is_authenticated() {
    const token = localStorage.getItem('access_token');
    //if token is not expired send on the way
    if (token && jwt_decode(token).exp > Date.now() / 1000) {
      return true;
    } else {
    // if token is expired try to refresh
    const refresh_token = localStorage.getItem('refresh_token');
    if(refresh_token) {
      axios.post(config.refresh_url,{},{
                  headers: {"Authorization": `Bearer ${refresh_token}`},
                  "crossdomain": true,
                  mode: 'no-cors',}).then(
                    response => {
                      const access_token = response.data.access_token;
                      localStorage.setItem('access_token', access_token)
                      return access_token ? true : false
                    }
                  )
      }
    }
    return false
  }

  render() {
    const client = this.client;
    return (
      <Router>
        <div>
          <Route exact path="/login" component={Login} />
          <PrivateRoute exact path="/" component={Home} authenticated={this.is_authenticated()} />
        </div>
      </Router>
    );
  }
}

export default App;

Since the Axios Call is async the component renders before the call is finished.

How can I make the render wait for the token to be refreshed?

Maximilian Kindshofer
  • 2,333
  • 3
  • 17
  • 31

1 Answers1

1

I'd keep isAuthenticated in the App components state. Then, you can use setState in the isAuthenticated call to cause a re-render on the result. This will also be important when the tokens expire.

R. Wright
  • 764
  • 3
  • 9