Basically I have an authentication application, where I have an authentication page where my user is sent every time the system does not recognize that he is authenticated, authentication occurs when he has a valid token registered in his localstorage with "authorization", so through "requireAuth" I created a mechanism where when a valid token is not identified in localstorage, the user is sent to the authentication page when he tries to access "/", and if he is authenticated, then he goes straight to "/ " and cannot access the auth page. This way
import { useContext } from "react"
import { AuthContext } from "./AuthContext"
import Authpage from "../pages/Authpage";
import { Navigate } from "react-router-dom";
export const RequireAuth = ({ children }: { children: JSX.Element }) => {
const auth = useContext(AuthContext);
if (!auth.user) {
return <Navigate to="/auth" replace />;
}
return children;
}
As you can see, the "/" page is protected
import { Routes, Route, useNavigate, useLocation } from 'react-router-dom';
import './App.css';
import Homepage from './pages/Homepage';
import Authpage from './pages/Authpage';
import Signuppage from './pages/Signuppage/Signuppage';
import { RequireAuth } from './context/RequireAuth';
import { RequireNotAuth } from './context/RequireNotAuth';
import React from 'react';
import GoogleAuthRedirect from './pages/GoogleAuthRedirect';
export function InvalidRoute() {
const navigate = useNavigate();
React.useEffect(() => {
navigate('/');
}, [navigate]);
return null;
}
function App() {
return (
<Routes>
<Route path='/' element={<RequireAuth><Homepage /></RequireAuth>} />
<Route path='/auth' element={<Authpage />} />
<Route path='/signup' element={<Signuppage />} />
<Route path='/googleauth/:id' element={<GoogleAuthRedirect />} />
</Routes>
);
}
export default App;
This is the part where my user gets thrown after authentication before being sent to "/"
import * as C from './styles';
import { useNavigate, useParams } from 'react-router-dom';
import { useContext, useEffect, useState } from 'react';
import { useApi } from '../../hooks/useApi';
import { AuthContext } from '../../context/AuthContext';
type Props = {}
const GoogleAuthRedirect = (props: Props) => {
const { id } = useParams();
const api = useApi();
const auth = useContext(AuthContext);
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
useEffect(() => {
const getToken = async() => {
try {
if (id) {
const token = await api.verifyToken(id);
setLoading(true);
setLoading(false);
if (token.success) {
localStorage.setItem('authorization', id);
setLoading(true);
setLoading(false);
navigate('/');
}
} else {
console.log("Token não definido.");
}
} catch (err) {
console.log(err);
}
}
getToken();
}, []);
return (
<div>
<h3>Autenticando...</h3>
</div>
)
}
export default GoogleAuthRedirect;
The problem is that after authenticating and sending the page "/", nothing is rendered on the page and it is only rendered if I press f5 and refresh the page. Somehow I thought it could be because it is being sent before authenticating in useEffect, so I tried loading it to extend this time and without success.
ps: Homepage
import { useContext, useEffect, useState } from 'react';
import * as C from './styles';
import { useNavigate } from 'react-router-dom';
import { useApi } from '../../hooks/useApi';
import { AuthContext } from '../../context/AuthContext';
type Props = {}
const Homepage = (props: Props) => {
const navigate = useNavigate();
const auth = useContext(AuthContext);
const api = useApi();
const [loading, setLoading] = useState(true);
useEffect(() => {
const verifyAuthTK = async () => {
const authorization = localStorage.getItem('authorization');
if (authorization) {
const isAuth = await api.verifyToken(authorization);
if (isAuth.success) {
setLoading(false);
}
}
};
verifyAuthTK();
}, []);
if (loading) {
return <div>Carregando...</div>;
}
return (
<C.Container>
homepage
</C.Container>
)
}
export default Homepage;
It sends me exactly to the "/" page that I would like, but the problem is that the screen is completely white and I need to press f5 to render the elements and components.