I'd like to use react with following flow:
Thing that I have now is:
App.js:
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/login" name="Login Page" component={Login} />
<Route path="/private" name="Private page" component={PrivatePage}/>
<Route path="/" name="Home" component={Index} />
</Switch>
</BrowserRouter>
);
}
}
PrivatePage.js:
import api from '../../api';
class PrivatePage extends Component {
state = {
first_name: '',
last_name: ''
};
componentDidMount() {
api.getProfile().then((res) => { /* this needs to be executed only if status code was 200 */
this.setState({
first_name: res.first_name,
last_name: res.last_name
})
})
}
render() {
return (
<div>
<p>first name: {this.state.first_name}</p>
<p>last name: {this.state.last_name}</p>
</div>
);
}
}
Api.js:
export class Api {
getProfile(){
return fetch('http://some_endpoint.com', {
method: 'GET',
body: '{}'
})
.then(/* probably something here needs to redirect to Login page in case of 401? */)
}
}
let api = new Api();
export default api;
This is of course simplified version of code- but shows my intention.
Use the Navigate element to set a default route with redirect in React Router, e.g. <Route path="/" element={<Navigate to="/dashboard" />} /> . The Navigate element changes the current location when it is rendered. Copied!
I think there are two ways.
Redirect from the backend. Or redirect on the front end via react-router (since youre using react-router)
using react router on the front end:
getProfile(){
return fetch('http://some_endpoint.com', {
method: 'GET',
body: '{}'
})
.then(/* probably something here needs to redirect to Login page in case of 401? */)
.catch((err)=>{
// you should get unauthorized.
this.setState({redirecting: true}) // this state is set which will render a react component called Redirect from react router
})
}
then in your render (note: youll need to import this)
render() {
return (
if(redirecting){
<Redirect to="/login">
}
// other stuff
)
}
for docs see: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Redirect.md
using express backend when you setup your authentication (here im using passport):
app.post(
'/api/login',
passport.authenticate('local', {
// successRedirect: '/profile',
// failureRedirect: '/error'
}),
(req, res) => {
res.send('authenticated!')
}
)
I'd suggest wrapping your Route components, the ones which needs to be protected, in some custom ProtectedRoute component which would access redux state, or would get some isAuthenticated prop, and then render Route. Protected routes.
Then on receiving 401 in your api call, just change isAuthenticated in state, or redux-state or whereever you're storing it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With