I’m using a Django + DRF backend with Djoser for auth, and a NextJS Frontend.
What I want to do is that during the login call on my Login component, I want to send a request to my backend (to Djoser on the /auth/users/me endpoint) to fetch the user object and redirect the user based on the role property.
Here’s the relevant part of the Login component:
'use client';
{/* imports */}
const Login = () => {
const {
register,
handleSubmit,
formState: { errors },
setError,
} = useForm<FormData>();
const router = useRouter();
const { login, storeToken, getToken } = AuthActions();
const { user, isError, isLoading, isValidating } = useUserData();
const accessToken = getToken('accessToken');
const onSubmit = async (data: FormData) => {
await login(data.email, data.password)
.json((json) => {
storeToken(json.access, 'access');
storeToken(json.refresh, 'refresh');
})
.catch((err) => {
setError('root', { type: 'manual', message: err.json.detail });
});
{/* redirect user based on user.role */}
// would be nice to show a spinner while it's validating or loading,
// but this won't work since we're running this in the onSubmit function I guess?
if (isLoading || isValidating || !accessToken) {
return <Spinner />;
}
if (isError) {
return <div>Error fetching user data</div>;
}
};
return (
{*/ return the Login component */}
};
export default Login;
My problem with the current implementation is that the await login()
function sets the JWT token which the fetcher needs.
Here’s the hook that should fetch the user object with SWR:
{/* imports */}
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
const useUserData = () => {
const { getToken } = AuthActions();
const accessToken = getToken('access');
// Is there a nicer way to make sure this hook only runs when there's an accessToken?
const { data, error, isLoading, isValidating } = useSWR(
accessToken ? '/auth/users/me' : null,
fetcher
);
return {
user: data,
isError: error,
isLoading: isLoading,
isValidating: isValidating,
};
};
export default useUserData;
I admit, I’m new to frontend development, I’m unclear on some concepts, patterns and best practices. I’m guessing I should store the user object in a context manager after fetching it – I wasn’t able to do that either.
Can nextjs-auth help me here? I don’t want to connect the frontend to the db or implement OAuth (yet), it was really easy to implement JWT auth with Djoser.