Reputation: 525
I'm trying to protect my routes in ReactJS. On each protected routes I want to check if the user saved in localStorage is good.
Below you can see my routes file (app.js) :
class App extends Component {
render() {
return (
<div>
<Header />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/signup" component={SignUp} />
<Route path="/contact" component={Contact} />
<ProtectedRoute exac path="/user" component={Profile} />
<ProtectedRoute path="/user/person" component={SignUpPerson} />
<Route component={NotFound} />
</Switch>
<Footer />
</div>
);
}
}
My protectedRoute file :
const ProtectedRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
AuthService.isRightUser() ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)} />
);
export default ProtectedRoute;
And my function isRightUser
. This function send a status(401)
when the data aren't valid for the user logged :
async isRightUser() {
var result = true;
//get token user saved in localStorage
const userAuth = this.get();
if (userAuth) {
await axios.get('/api/users/user', {
headers: { Authorization: userAuth }
}).catch(err => {
if (!err.response.data.auth) {
//Clear localStorage
//this.clear();
}
result = false;
});
}
return result;
}
This code is not working and I don't know really why.
Maybe I need to call my function AuthService.isRightUser()
with a await
before the call and put my function async ?
How can I update my code to check my user before accessing a protected page ?
Upvotes: 2
Views: 4179
Reputation: 4481
When you annotate a function with async
like you did in AuthService.isRightUser()
it returns a Promise
and you are not treating the response of the method accordingly.
As you suggested, you could call the method AuthService.isRightUser()
with await
and annotate the function you are passing to the render
property with async
.
Or you could treat the response of AuthService.isRightUser()
with a .then()
and .catch()
instead of the ternary operator
Upvotes: 0
Reputation: 1354
I had the same issue and resolved it by making my protected route a stateful class.
Inside switch I used
<PrivateRoute
path="/path"
component={Discover}
exact={true}
/>
And my PrivateRoute class is as following
class PrivateRoute extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
isLoading: true,
isLoggedIn: false
};
// Your axios call here
// For success, update state like
this.setState(() => ({ isLoading: false, isLoggedIn: true }));
// For fail, update state like
this.setState(() => ({ isLoading: false, isLoggedIn: false }));
}
render() {
return this.state.isLoading ? null :
this.state.isLoggedIn ?
<Route path={this.props.path} component={this.props.component} exact={this.props.exact}/> :
<Redirect to={{ pathname: '/login', state: { from: this.props.location } }} />
}
}
export default PrivateRoute;
Upvotes: 6