I have created a hook called useAuth.ts:
const useAuth = (requiredRole: string) => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const { currentUser, status } = useAppSelector((state) => state.user);
const loading = useAppSelector((state) => state.loading.loading);
useEffect(() => {
if (status === 'idle') {
console.log('Dispatching loadUser');
dispatch(loadUser());
}
}, [status, dispatch]);
useEffect(() => {
console.log('Auth Check: Current User:', currentUser);
console.log('Auth Check: Required Role:', requiredRole);
console.log('Auth Check: Status:', status);
console.log('Auth Check: Loading:', loading);
if (!loading && status === 'succeeded') {
if (!currentUser) {
console.log('No current user, redirecting to login');
navigate('/login');
} else if (currentUser.role !== requiredRole) {
console.log('User role does not match required role, redirecting to home');
navigate('/');
}
}
}, [currentUser, status, loading, navigate, requiredRole]);
};
export default useAuth;
This hook is used to check for a single page I have called adminPanel.
Currently, when I try to access the page while logged in as a admin user, it redirects me to the /login page anyways.
Here is our sessionLoader.tsx:
const SessionLoader: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const dispatch = useDispatch<AppDispatch>();
const { currentUser, status } = useSelector((state: RootState) => state.user);
const loading = useSelector((state: RootState) => state.loading.loading);
useEffect(() => {
const token = localStorage.getItem('sessionToken');
if (token && status === 'idle') {
console.log('Token Found:', token);
dispatch(loadUser());
}
}, [dispatch, status]);
useEffect(() => {
console.log('SessionLoader: CurrentUser:', currentUser);
console.log('SessionLoader: Status:', status);
console.log('SessionLoader: Loading:', loading);
}, [currentUser, status, loading]);
if (status === 'loading' || loading) {
return (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
}}
>
<CircularProgress />
</Box>
);
}
return <>{children}</>;
};
export default SessionLoader;
We have a userSlice.ts, that handles the loadUser action:
export const loadUser = createAsyncThunk(
'users/loadUser',
async (_, { rejectWithValue, dispatch }) => {
dispatch(setLoading(true));
const token = localStorage.getItem('sessionToken');
if (!token) {
dispatch(setLoading(false));
return rejectWithValue('No session token found');
}
try {
const userResponse = await axiosInstance.get('/api/users/verify/me', {
headers: {
Authorization: `Bearer ${token}`,
},
});
const user = userResponse.data.user;
dispatch(setLoading(false));
return user;
} catch (err) {
let errorMessage = 'An unknown error occurred';
if (axios.isAxiosError(err) && err.response) {
errorMessage = err.response.data?.message || err.message;
} else if (err instanceof Error) {
errorMessage = err.message;
}
dispatch(setLoading(false));
return rejectWithValue(errorMessage);
}
}
);
For the life of me, I cant get it to display the page correctly. It seems like the page is redirecting before it can verify the user. Here is our chrome console logs when trying to access the restricted page:
If you need any more specific code, ask away. Ive spent two days trying to figure this out so i’m open to any and all help! Thanks in advance 🙂
I am expecting the currentUser
details to load, be verified, and load the admin page. But instead, its kicking me back to the /login page as if we are not logged into an admin account. I can see in the network tab in chrome devtools that the actual content of the admin page is loaded.