我无法在 Next.js 14 的 GET 方法中从会话中获取 ID

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

我创建了一个 api 路由来处理当前登录用户创建的

getAllAddresses
。但我只得到一个空数组。我想象 req 无法获取当前登录用户的 ID。我检查了 nextauth 配置并获得了 ID。

为了更加确定,我在 nextauth 上 console.log 会话配置并获取 ID,如下所示:

 🚀 ~ session ~ session: {
  user: {
    name: 'Nhung Nguyen',
    email: '[email protected]',
    image: 'https://lh3.googleusercontent.com/a/ACg8ocLg8TfKh72d8RDiUO9xIxR7CTgR4e6hU8WpwTtlXHEDEIg=s96-c',
    id: '65ff0b9c80353678f60e337a'
  },
  expires: '2024-04-27T13:26:30.889Z'
}

但是在api路由句柄getAllAddresses上,我收到的会话只有姓名、电子邮件、图像,没有ID。这是我在 api 路由句柄 getAllAddresses 处的日志:

🚀 ~ GET ~ session: {
  user: {
    name: 'Nhung Nguyen',
    email: '[email protected]',
    image: 'https://lh3.googleusercontent.com/a/ACg8ocLg8TfKh72d8RDiUO9xIxR7CTgR4e6hU8WpwTtlXHEDEIg=s96-c'
  }
}

这是我在 api/auth/[...nextauth]/route.js 中的代码

    const handler = NextAuth({
    providers: [
        CredentialsProvider({
            name: 'credentials',
            credentials: {},
            async authorize(credentials, req) {
                await connect()

                const user = await User.findOne({ email: credentials.email })

                if (!user) {
                    throw new Error('Đăng nhập không hợp lệ!')
                }

                const comparePassword = await bcrypt.compare(credentials.password, user.password)

                if (!comparePassword) {
                    throw new Error('Đăng nhập không hợp lệ!')
                }

                return user
            }
        }),
        GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET
        }),
    ],
    session: {
        strategy: 'jwt'
    },
    pages: {
        signIn: '/login'
    },
    secret: process.env.NEXTAUTH_SECRET,
    callbacks: {
        async signIn({ profile, account }) {
            if (account.provider === 'google') {
                try {
                    await connect()
                    let user = await User.findOne({ email: profile.email })
                    if (!user) {
                        user = await User.create({
                            email: profile.email,
                            name: profile.name,
                            avatar: profile.image,
                            wishlist: [],
                            cart: [],
                            orders: [],
                            products: []
                        })
                    }
                    return user

                } catch (error) {
                    console.log(error)
                }
            }
            return true
        },
        async jwt({ token, user }) {
            user && (token.user = user)

            return token
        },
        async session({ session }) {
            const sessionUser = await User.findOne({ email: session.user.email })
            // console.log('🚀 ~ session ~ sessionUser:', sessionUser)

            session.user.id = sessionUser._id.toString()
            console.log('🚀 ~ session ~ session.user.id:', session.user.id)

            console.log('🚀 ~ session ~ session:', session)

            return session
        }
    }
})

export { handler as GET, handler as POST }

这是我在 api 路由句柄 getAllAddresses 的代码

export async function GET(req) {
    try {
        const session = await getServerSession({ req })
        console.log('🚀 ~ GET ~ session:', session)

        if (!session) {
            return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
        }
        const getAllAddresses = await Address.find({ userID: session.user.id })

        if (getAllAddresses) {
            return NextResponse.json({
                success: true,
                data: getAllAddresses,
            });
        } else {
            return NextResponse.json({
                success: false,
                message: "failed to get addresses ! Please try again",
            });
        }
    } catch (error) {
        console.error('Error fetching user addresses:', error)
        return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 })
    }
}
session next.js
2个回答
0
投票

我在 Next Auth 文档中搜索了更多内容。我发现您错误地使用了

getServerSession
。在 V4 中,当您使用应用程序路由器时,您必须仅将下一个身份验证选项传递给此函数。更多信息可以在这里找到(https://next-auth.js.org/configuration/nextjs#in-app-router

但是,我会给您一个示例,您可以立即在代码中使用它。

首先,您应该导出Next Auth的配置。像这样:

// app/api/auth/[...nextauth]/route.js
export const authOptions = {
    providers: [...],
    session: ...,
    ...
}

const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }

之后,您可以创建一个名为

auth.js
或其他名称的 util 文件,并将此函数放入其中:

import {authOptions} from "app/api/[...nextauth]/route.js"

export const auth = () => getServerSession(authOptions)

最后,你可以在任何你想要的地方导入这个函数并调用它:

export const POST = async () => {
   const session = await auth();

   ...
}

0
投票

您必须提供会话回调:

callbacks: {
  async session({ session, token, user }) {
    // Send properties to the client, like an access_token and user id from a provider.
    session.accessToken = token.accessToken
    session.user.id = token.id
    
    return session
  }
}

并将 id 从 use 或 token 对象添加到会话中。 参考:https://next-auth.js.org/configuration/callbacks

© www.soinside.com 2019 - 2024. All rights reserved.