Following issue: I am trying to create an authentication system in react, which let's a user login, sign up and reset the password. The problem is, I want to let the user go certain routes such as /profile, but display the content if he is logged in. If he is not logged in, I want to simply display the navigation bar and a small login component.
So far I tried something like this: (In order to make it more readable I left out the action-blocks)
const Profile = ({ history }) => {
const [values, setValues] = useState({
username: "",
email: "",
password: ""
});
const [isShowingAuth, setIsShowingAuth] = useState(null);
const { username, email, password } = values;
useEffect(() => {
if (!isLoggedIn()) {
setIsShowingAuth("login");
} else {
loadProfileData();
}
}, []);
const loadProfileData = () => {
const userEmail = isLoggedIn().email;
const token = getCookie("token");
axios({
method: "GET",
url: `${process.env.REACT_APP_BACKEND_URL}/user`,
headers: { Authorization: `Bearer ${token}` },
data: { userEmail }
})
.then(response => {
// Do something
})
.catch(error => {
// Do something
});
};
const handleChange = name => event => {
setValues({ ...values, [name]: event.target.value });
};
const handleUpdateUserSubmit = e => {
e.preventDefault();
const token = getCookie("token");
axios({
method: "PUT",
url: `${process.env.REACT_APP_BACKEND_URL}/user/update`,
headers: { Authorization: `Bearer ${token}` },
data: { username, password, email }
})
.then(response => {
// Do something
})
.catch(error => {
// Do something
}
store.addNotification({
...defaultSettings,
type: "danger",
title: "User update error",
message: error.response.data.errorMsg
});
});
};
const deleteAccount = () => {
const token = getCookie("token");
axios({
method: "DELETE",
url: `${process.env.REACT_APP_BACKEND_URL}/user`,
headers: { Authorization: `Bearer ${token}` }
})
.then(response => {
// Do something
})
.catch(error => {
// Do something
};
const showDeleteConfirmation = () => {
// Do something
};
return (
<Layout isShowingAuth={isShowingAuth}>
{isLoggedIn() && isLoggedIn().role === "member" ? (
<>
<ReactNotifications />
<h1 className='mt-5 pl-3'>Profile</h1>
<form className='form col-md-6 mt-3'>
<div className='form-group'>
<label>Name</label>
<input
type='text'
className='form-control'
value={username}
onChange={handleChange("username")}
/>
</div>
<div className='form-group'>
<label>Email</label>
<input
type='email'
className='form-control'
value={email}
onChange={handleChange("email")}
disabled
/>
</div>
<div className='form-group'>
<label>Password</label>
<input
type='password'
className='form-control'
value={password}
onChange={handleChange("password")}
placeholder='Enter your new password'
autoComplete='on'
/>
</div>
<button type='submit' className='btn btn-outline-primary' onClick={handleUpdateUserSubmit}>
Update User
</button>
<button type='button' className='btn btn-outline-danger ml-3' onClick={showDeleteConfirmation}>
Delete account
</button>
<button type='button' className='btn btn-outline-danger ml-3 mt-2 mt-md-0'>
Want to change your email?
</button>
</form>
{showAlert}
</>
) : null}
</Layout>
);
};
Basically I am checking through the isLoggedIn()
method if the user is logged in. If he is, I want to render the content, if not I am returning only the layout. The layout contains the navigation bar.
The problem now is, that once the user logs in while being on the route /profile, the component doesn't remount, which means the useEffect(()=> {},[])
is not called again and my profile data is not loaded.
I already tried to refresh the page once logged in through history.push(history.location.pathname)
, but this doesn't trigger a remount either.
I'm no wondering how to properly trigger a remount after login, and if the way I am setting my authentication system up is secure or if there are better solutions.
Any help / feedback appreciated thanks :)