Reputation: 113
i am securing routes using redux states. What i am doing is when user loggedIn i update redux state isAuthenticated
in signIn
component and receiving that state in my AllRoutes
component and then i passed it in my custom route ProtectedHomeRoute
as props. Everything is working fine but problem is when i refresh, i get isAuthenticated
value false
which is default value of it so because of this, ProtectedHomeRoute
redirect me to Login
page.
Please suggest me the best way to handle browser refresh on above mentioned use case.
i tried to solve this in this way that i made a new action named isLoggedIn
in this i am calling API to check login status, if response is then i am passing true in payload
then i am calling this action in componentDidMount
lifecyle of AllRoutes
so that when browser will refresh isLoggedIn
will be called and ill get previous state but things is not happening is this way.
This is code of isLoggedIn
action
export function isLoggedIn() {
axios.get("http://localhost:8080/api/checkLoginStatus").then(res => {
let data = res.data;
let tid = data.data; // data contain userId
console.log(tid);
let isAuthenticate = false
if(tid){
isAuthenticate = true;
}
return dispatch => {
dispatch({
type: "isLoggedIn",
payload: isAuthenticate
});
};
})
}
THis is auth Reducer code
const INITIAL_STATE = {
isAuthenticate: false
};
export default (states = INITIAL_STATE, action) => {
switch (action.type) {
case "loggedIn":
return {
...states,
isAuthenticate: action.payload
};
case "logOut":
return {
...states,
isAuthenticate: action.payload
};
case "isLoggedIn":
return {
...states,
isAuthenticate: action.payload
};
default:
return states;
}
};
AllRouts component code
import { isLoggedIn } from "./store/action/authAction";
import axios from 'axios';
class AllRoutes extends React.Component {
componentDidMount() {
isLoggedIn();
}
render() {
console.log(this.props.isAuthenticate);
return (
<Router>
<Switch>
<Route path="/auth/signup" component={Signup} />
<Route path="/auth/signin" component={Signin} />
<Route path="/auth/forgot" component={Forgot} />
<Route exact path="/stock" component={Products} />
<Route exact path="/stock/detail/:id" component={Manage} />
<ProtectedHomeRoute
exact
path="/"
component={<Home />}
isAuthenticate={this.props.isAuthenticate}
/>
</Switch>
</Router>
);
}
}
// to access redux stats as props in this component
function mapStateToProps(state) {
return {
isAuthenticate: state.authReducer.isAuthenticate
};
}
function mapDispatchToProps(dispatch) {
return {
userAuthenticate: a => {
dispatch(isLoggedIn(a));
}
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(AllRoutes);
// protected route for Home component
const ProtectedHomeRoute = ({ component, isAuthenticate, ...rest }) => {
console.log("protected route", isAuthenticate);
return (
<Route
{...rest}
render={props =>
isAuthenticate ? component : <Redirect to="/auth/signin" />
}
/>
);
};
Upvotes: 2
Views: 6871
Reputation: 103
From your code i'm guessing that you are more of a front-end developer. you shouldn't use userId for authentication. you have to use something like jwt with expiration at your back-end. with jwt you can create a token for every logged in user. keep the token in LocalStorage and pass it as header with every request and make your private route require that token. you can read jwt documentation and this should give you an idea of how it would look like:
Auth actions auth actions
Auth reducer auth reducer
Private Route Private route
Upvotes: 5