代码之家  ›  专栏  ›  技术社区  ›  klng

我无法在NEXTJS14中的get方法中从会话中获取ID!请帮我找出错误

  •  0
  • klng  · 技术社区  · 2 年前

    我创建了一个 api路由 来处理 获取所有地址 c 当前登录的用户 已创建。但我只得到一个空数组。我想象req无法获得当前登录用户的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/[…nexttauth]/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 })
        }
    }
    
    2 回复  |  直到 2 年前
        1
  •  0
  •   Arash jahan bakhshan    2 年前

    我在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 或者其他什么,并将此函数放入其中:

    import {authOptions} from "app/api/[...nextauth]/route.js"
    
    export const auth = () => getServerSession(authOptions)
    

    最后,您可以将此函数导入任意位置并调用它:

    export const POST = async () => {
       const session = await auth();
    
       ...
    }
    
        2
  •  0
  •   Neer Amrutia    2 年前

    您必须提供会话回调:

    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