Next.js Discord

Discord Forum

Cant access all the Session Data when using next_auth and getServerSession in API routes

Unanswered
Hamodi posted this in #help-forum
Open in Discord
The code for my API route where i want to get the session role, I am only getting the name and email:
export async function GET(req, res) {
    try {
        const session = await getServerSession({ req, res });

        if (!session) {
            return new NextResponse(
                JSON.stringify({
                    error: 'Unauthorized',
                }),
                {
                    status: 401,
                }
            );
        }

        if (session.user.role !== 'ADMIN') {
            return new NextResponse(
                JSON.stringify({
                    error: 'Permission Denied',
                }),
                {
                    status: 403,
                }
            );
        }

        const users = await prisma.user.findMany({
            where: {
                role: "USER"
            }
        });

        if (users.length === 0) {
            return new NextResponse(
                JSON.stringify({
                    error: 'Not Found',
                }),
                {
                    status: 404,
                }
            );
        }

        return NextResponse.json(users);

    } catch (error) {
        return new NextResponse(
            JSON.stringify({
                error: 'Internal Server Error',
                details: error.message,
            }),
            {
                status: 500,
            }
        );
    }
}

The code for the ..nextauth:
export const authOptions = {
    session: {
        strategy: 'jwt',
    },
    providers: [
        CredentialsProvider({
            name: 'Sign in',
            credentials: {
                email: {
                    type: 'email',
                },
                password: {
                    type: 'password',
                },
            },
            async authorize(credentials) {
                if (!credentials?.email || !credentials.password) {
                    return null;
                }

                const user = await prisma.user.findUnique({
                    where: {
                        email: credentials.email,
                    }
                });

                if (!user) {
                    throw new Error('Invalid e-mail or password');

                }

                const isPasswordValid = await compare(credentials.password, user.password);

                if (!isPasswordValid) {
                    throw new Error('Invalid e-mail or password');
                }

                return {
                    name: user.name,
                    phoneNumber: user.phoneNumber,
                    email: user.email,
                    role: user.role,
                };
            },
        }),
    ],

    pages: {
        signIn: '/',
    },

    callbacks: {
        session: async ({ session, token }) => {
            console.log('Session Callback', { session, token });
            return {
                ...session,
                user: {
                    ...session.user,
                    id: token.id,
                    name: token.name,
                    email: token.email,
                    phoneNumber: token.phoneNumber,
                    role: token.role,
                },
            };
        },
        jwt: async ({ token, user }) => {
            console.log('JWT Callback', { token, user });
            if (user) {
                const u = user;
                return {
                    ...token,
                    id: u.id,
                    name: u.name,
                    email: u.email,
                    phoneNumber: u.phoneNumber,
                    role: u.role,
                };
            }
            return token;
        },
    },
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

15 Replies

@Hamodi The code for my API route where i want to get the session role, I am only getting the name and email:js export async function GET(req, res) { try { const session = await getServerSession({ req, res }); if (!session) { return new NextResponse( JSON.stringify({ error: 'Unauthorized', }), { status: 401, } ); } if (session.user.role !== 'ADMIN') { return new NextResponse( JSON.stringify({ error: 'Permission Denied', }), { status: 403, } ); } const users = await prisma.user.findMany({ where: { role: "USER" } }); if (users.length === 0) { return new NextResponse( JSON.stringify({ error: 'Not Found', }), { status: 404, } ); } return NextResponse.json(users); } catch (error) { return new NextResponse( JSON.stringify({ error: 'Internal Server Error', details: error.message, }), { status: 500, } ); } } The code for the ..nextauth:js export const authOptions = { session: { strategy: 'jwt', }, providers: [ CredentialsProvider({ name: 'Sign in', credentials: { email: { type: 'email', }, password: { type: 'password', }, }, async authorize(credentials) { if (!credentials?.email || !credentials.password) { return null; } const user = await prisma.user.findUnique({ where: { email: credentials.email, } }); if (!user) { throw new Error('Invalid e-mail or password'); } const isPasswordValid = await compare(credentials.password, user.password); if (!isPasswordValid) { throw new Error('Invalid e-mail or password'); } return { name: user.name, phoneNumber: user.phoneNumber, email: user.email, role: user.role, }; }, }), ], pages: { signIn: '/', }, callbacks: { session: async ({ session, token }) => { console.log('Session Callback', { session, token }); return { ...session, user: { ...session.user, id: token.id, name: token.name, email: token.email, phoneNumber: token.phoneNumber, role: token.role, }, }; }, jwt: async ({ token, user }) => { console.log('JWT Callback', { token, user }); if (user) { const u = user; return { ...token, id: u.id, name: u.name, email: u.email, phoneNumber: u.phoneNumber, role: u.role, }; } return token; }, }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
Since you are using JWT, try using getToken instead of getServerSession.
@ncls. Since you are using JWT, try using `getToken` instead of `getServerSession`.
something like this:
import { getToken } from "next-auth/jwt"

const secret = process.env.NEXTAUTH_SECRET

export default async function handler(req, res) {
  // if using `NEXTAUTH_SECRET` env variable, we detect it, and you won't actually need to `secret`
  // const token = await getToken({ req })
  const token = await getToken({ req, secret })
  console.log("JSON Web Token", token)
  res.end()
}
Exactly
But as long as your secret is called "NEXTAUTH_SECRET", you don't have to pass it. The function will grab it automatically
@ncls. Exactly
It worked, I am getting all the data when using
getToken
But not when using
getServerSession
Do you have any ideas why?
@Hamodi It worked, I am getting all the data when using getTokenBut not when using getServerSession Do you have any ideas why?
Nope, no idea. But I tried it in a couple of different ways and it just returns the standard info for me as well
@ncls. Nope, no idea. But I tried it in a couple of different ways and it just returns the standard info for me as well
Same here, but when console.log the session in the ...nextauth route then it will get all the data. It is very confusing.
@Hamodi The code for my API route where i want to get the session role, I am only getting the name and email:js export async function GET(req, res) { try { const session = await getServerSession({ req, res }); if (!session) { return new NextResponse( JSON.stringify({ error: 'Unauthorized', }), { status: 401, } ); } if (session.user.role !== 'ADMIN') { return new NextResponse( JSON.stringify({ error: 'Permission Denied', }), { status: 403, } ); } const users = await prisma.user.findMany({ where: { role: "USER" } }); if (users.length === 0) { return new NextResponse( JSON.stringify({ error: 'Not Found', }), { status: 404, } ); } return NextResponse.json(users); } catch (error) { return new NextResponse( JSON.stringify({ error: 'Internal Server Error', details: error.message, }), { status: 500, } ); } } The code for the ..nextauth:js export const authOptions = { session: { strategy: 'jwt', }, providers: [ CredentialsProvider({ name: 'Sign in', credentials: { email: { type: 'email', }, password: { type: 'password', }, }, async authorize(credentials) { if (!credentials?.email || !credentials.password) { return null; } const user = await prisma.user.findUnique({ where: { email: credentials.email, } }); if (!user) { throw new Error('Invalid e-mail or password'); } const isPasswordValid = await compare(credentials.password, user.password); if (!isPasswordValid) { throw new Error('Invalid e-mail or password'); } return { name: user.name, phoneNumber: user.phoneNumber, email: user.email, role: user.role, }; }, }), ], pages: { signIn: '/', }, callbacks: { session: async ({ session, token }) => { console.log('Session Callback', { session, token }); return { ...session, user: { ...session.user, id: token.id, name: token.name, email: token.email, phoneNumber: token.phoneNumber, role: token.role, }, }; }, jwt: async ({ token, user }) => { console.log('JWT Callback', { token, user }); if (user) { const u = user; return { ...token, id: u.id, name: u.name, email: u.email, phoneNumber: u.phoneNumber, role: u.role, }; } return token; }, }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
@joulev Maybe this? https://github.com/nextauthjs/next-auth/issues/7423
But it's not null. It just returns the default info (name, email, image) without any custom info you add in the callbacks.
Hmm no idea then
@ncls. But it's not null. It just returns the default info (name, email, image) without any custom info you add in the callbacks.
Yes?
What's with that?