I have this authentication flow on nextjs in a layout component wrapping al my application routes. This is my code:
I have all the logic inside a useEffect and the return of this <Layout/> is any {children}
useEffect(() => {
setLoading(true)
const checkToken = async () => {
const token = localStorage.getItem('FBIdToken')
//si hay un token en el localstorage
if (token) {
const decodedToken = jwtDecode(token);
const res = await getNewToken();
//Si el token expira
if (decodedToken.exp * 1000 < Date.now()) {
if (res.access_token) {
localStorage.setItem('FBIdToken', res.access_token)
} else {
localStorage.clear('FBIdToken');
}
} else {
if (router.pathname == '/login' || router.pathname == '/register') {
router.push('/');
}
if (!userFromDB) {
let user = await getUser(decodedToken.user_id);
user.id = decodedToken.user_id
//si encontro un usuario, lo asignamos al context api
if (user) {
// obtenemos el objecto con los datos del usuario y seteamos en el context si es vendedor o no
if (typeof user.isVender !== undefined) {
user.isVender ? setIsVender(true) : setIsVender(false);
} else {
router.pathname !== '/suscripcion-request' ? router.push('/') : ''
}
setUserFromDB(user);
}
setAuthenticated(true)
}
}
} else {
if (allowedRoutesForEveryone.indexOf(router.pathname) < 0) {
router.replace('/login')
}
}
setLoading(false);
}
//comprobamos que haya un token y redirigimos al usuario en base a el
checkToken();
}, [router.pathname])
This is slow because the component returns the children and then checks if the users is logged in. This causes the redirect of private pages to be slow and it allows me to interact with the content for half a second before the redirect which is not very secure.
I know there are many libraries for this approach such as NextAuth or oauth2 but I don't know if there is one that allows me just to decode a token. Should I put this logic in a middleware? Something else?
I hope you can help me. Thanks in advance!