This is a work in progress. We will update the page once implementated.
Authentication with TS-Rest and Next-Auth (Auth.js) is implemented by utizing the JWT tokens that Next-Auth manages.
- Since Next-Auth has no way to get the this token on the frontend, we implement a route in our NextJS app called
/token
.
This route gets the token on the server, decodes and decrypts it. Encodes it again with our secret and then is passed to the Authentication header with every request to our backend.
export async function GET(req: NextRequest) {
const token = await getToken({
req,
secret: env.NEXTAUTH_SECRET,
});
const jwtToken = jwt.sign(
{
...token,
},
env.NEXTAUTH_SECRET,
{
algorithm: "HS256",
}
);
return NextResponse.json({ token: jwtToken });
}
-
On the backend, this header is read and the object is written to the
Request
as auth
.
-
We can include any information like User Roles, Dates of Birth etc. to this object by tweaking the auth options of Next-Auth. For example:
callbacks: {
async jwt({ token, user }) {
if (user) {
token.role = user.role;
}
return token;
},
async session({ session, token }) {
if (token?.role) {
//@ts-ignore
session.user.role = token.role;
}
//add the user id to the session
session.user.id = token.sub ?? "";
return session;
},
},
This adds the user.role
and user.uid
to the auth object (Provided that
exists in the database).
Next Auth Session Hook with Loading
import { useState, useEffect } from 'react';
import { useSession } from 'next-auth/react'; // replace 'your-session-library' with the actual library you're using
function useSessionWithLoading() {
const [loading, setLoading] = useState(true);
const { data: session } = useSession();
useEffect(() => {
// If session data is not yet available (still loading), set loading to true
if (session === undefined) {
setLoading(true);
} else {
setLoading(false);
}
}, [session]);
return { loading, session }
}
export default useSessionWithLoading;