NextAuth getServerSession() 不返回 API 路由中的所有用户字段

问题描述 投票:0回答:1

我正在尝试编写一个 API 路由,我想在其中检查用户是否经过身份验证以及它是否是管理员。为此,我尝试调用 getServerSession 方法,它确实返回一个会话,但我的自定义字段设置为“未定义”,还要注意,如果我在 getServerSideProps(ctx) 中使用相同的方法,它会按预期工作,所以这只发生在API 路由。

API 路由中的会话对象:不返回预期的 Console log of the session object in api route

getServerSideProps 中的会话对象:返回预期的 Console log of the session object in getServerSideProps

[..nextauth].ts

import type { NextAuthOptions, Session } from 'next-auth';
import NextAuth from 'next-auth';
import type { JWT } from 'next-auth/jwt';
import CredentialsProvider from 'next-auth/providers/credentials';

import { verifyPassword } from '@/lib/auth';
import { connectToDatabase, initUserTable } from '@/lib/db';
import User from '@/lib/dbmodels/user';

export const authOptions: NextAuthOptions = {
    secret: process.env.NEXTAUTH_SECRET,
    session: {
        strategy: 'jwt',
    },
    providers: [
        CredentialsProvider({
            name: 'Credentials',
            credentials: {
                email: { label: 'Email', type: 'text' },
                password: { label: 'Password', type: 'password' },
            },
            async authorize(credentials) {
                if (!credentials?.email || !credentials?.password) {
                    throw new Error('Email-ul sau parola sunt greșite');
                }
                const db = await connectToDatabase();
                await initUserTable(db);
                const user = await User.findOne({
                    where: { email: credentials?.email },
                });
                if (!user) {
                    db.close();
                    throw new Error('Acest utilizator nu există');
                }
                const isValid = await verifyPassword(
                    credentials?.password,
                    user.password
                );
                if (!isValid) {
                    db.close();
                    throw new Error('Email-ul sau parola sunt greșite');
                }
                db.close();

                return user.dataValues;
            },
        }),
    ],
    callbacks: {
        async jwt({ user, token }) {
            const newToken = { ...token };
            if (user?.role) {
                newToken.role = user.role;
            }
            if (user?.id) {
                newToken.id = user.id;
            }
            return newToken;
        },
        async session({ session, token }: { session: Session; token: JWT }) {
            const newSession = { ...session };
            newSession.user.role = token.role as 'user' | 'admin';
            newSession.user.id = token.id as string;
            delete newSession.user.image;
            return newSession;
        },
    },
};

export default NextAuth(authOptions);

API 路线

async function handler(req: RegisterNextApiRequest, res: NextApiResponse) {
    if (req.method !== 'POST') {
        return res.status(405).json({ error: 'Method not supported' });
    }

    const { name, email, password, role = 'user' } = req.body;

    const emptyData = name == null || email == null || password == null;

    const session = await getServerSession(req, res, authOptions);

    const user = session?.user;

    if (!user || !user?.email) {
        return res.status(401).json({ error: 'You must be logged in.' });
    }

    if (user?.role !== 'admin') {
        return res.status(401).json({ error: 'Only admins can create users!' });
    }

    // Rest of the code
}

类型文件

import type { DefaultSession } from 'next-auth';

declare module 'next-auth' {
    interface Session {
        user: User & DefaultSession['user'];
    }

    interface User {
        id: string;
        name: string;
        email: string;
        role?: 'user' | 'admin';
    }
}

我也希望能够在 API 路由中访问角色对象,但似乎只能在 getServerSideProps() 下一个函数中访问。

reactjs api next.js next
1个回答
0
投票

别忘了扩展

SessionBase

  interface Session extends SessionBase {
    user?: User
  }
© www.soinside.com 2019 - 2024. All rights reserved.