I'm working with NextJS, Next-auth and Django as backend. I'm using the credentials provider to authenticate users. Users are authenticated against the Django backend and the user info together with the accesstoken is stored in the session.
I'm trying to use useSWR now to fetch data from the backend. (no preloading for this page required, that's why I'm working with SWR) I need to send the access_token from the session in the fetcher method from useSWR. However I don't know how to use useSWR after the session is authenticated. Maybe I need another approach here.
I tried to wait for the session to be authenticated and then afterwards send the request with useSWR, but I get this error: **Error: Rendered more hooks than during the previous render.
**
Could anybody help with a better approach to handle this? What I basically need is to make sure an accesstoken, which I received from a custom backend is included in every request in the Authorization Header. I tried to find something in the documentation of NextJS, Next-Auth or SWR, but I only found ways to store a custom access_token in the session, but not how to include it in the Header of following backend requests.
This is the code of the component:
import { useSession } from "next-auth/react";
import useSWR from 'swr';
import axios from 'axios'
export default function Profile() {
const { data: session, status } = useSession();
// if session is authenticated then fetch data
if (status == "authenticated") {
// create config with access_token for fetcher method
const config = {
headers: { Authorization: `Bearer ${session.access_token}` }
};
const url = "http://mybackend.com/user/"
const fetcher = url => axios.get(url, config).then(res => res.data)
const { data, error } = useSWR(url, fetcher)
}
if (status == "loading") {
return (
<>
<span>Loading...</span>
</>
)
} else {
return (
<>
{data.email}
</>
)
}
}
you don't need to check status
every time. what you need to do is to add this function
to your app.js
file
function Auth({ children }) {
const router = useRouter();
const { status } = useSession({
required: true,
onUnauthenticated() {
router.push("/sign-in");
},
});
if (status === "loading") {
return (
<div> Loading... </div>
);
}
return children;
}
then add auth
proprety to every page that requires a session
Page.auth = {};
finally update your const App
like this
<SessionProvider session={pageProps.session}>
<Layout>
{Component.auth ? (
<Auth>
<Component {...pageProps} />
</Auth>
) : (
<Component {...pageProps} />
)}
</Layout>
</SessionProvider>
so every page that has .auth
will be wrapped with the auth
component and this will do the work for it
now get rid of all those if
statments checking if session
is defined since you page will be rendered only if the session
is here