Sem poder validar o token não haverá nenhuma rota privada. Nesse caso você apenas verifica se existe um token, isso significa que é possível injetar esse token no localstorage e pronto, a pessoa já tem acesso a rota privada sem autenticação.
Em questão de lógica, acredito que inverter as condicionais será mais vantajoso. Basicamente você tem apenas um caso onde o componente <Outlet />
será exibido, que é quando o usuário está devidamente autenticado. Invertendo as condicionais ficaria algo mais ou menos assim:
const storageToken = JSON.parse(localStorage.getItem("token"));
if(!storageToken || !storageToken.token_type)){
return (<Navigate to="/login" />)
}
// outras condições aqui
return <Outlet />
Dessa forma ficaria muito mais fácil para adicionar mais casos onde o usuário seria redirecionado para a página de login, inclusive evitando requisições desnecessárias para o backend.
Outra melhoria sutil seria utilizar async - await
ao invés de .then
com promisses. Por exemplo, a sua requisição post ficaria assim (estou assumindo que você está usando o axios):
// no axios um erro é retornado quando você recebe um código http de erro
try {
const { data } = await api.post("/login", {
username: username,
psswd: password,
})
localStorage.setItem("token", JSON.stringify(data))
return { success: true, message: "login realizado com sucesso" }
} catch (err) {
// trata o erro no login
return { success: false, message: "login não realizado" } // ou algo do tipo
}
Repare que, mesmo com o código ficando maior a leitura e o controle sobre ele são melhores com essa sintaxe. No caso de adicionar esse código dentro de um componente você o colocaria dentro de uma função assíncrona, que pode ser declarada dentro do próprio componente, daí sim utilizaria a sintaxe .then()
dentro do componente, mas agora apenas receberia o resultado do login, sem precisar se preocupar com a lógica da requisição.