You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextAuth v4中API路由内getSession始终返回null问题排查

问题:Next.js中调用getSession/unstable_getServerSession始终返回null

我正在Next.js应用中集成Stripe,尝试引导用户进入结账流程,但在/pages/api/subscribe.ts文件中获取会话信息时遇到问题。使用getSession或unstable_getServerSession都始终返回null,控制台打印显示请求的Cookies正常,用户已通过NextAuth的GitHub集成登录。以下是相关代码,请帮忙排查哪里操作有误?


subscribe.ts代码

import { NextApiRequest, NextApiResponse } from "next";
// import { unstable_getServerSession } from "next-auth/next";
import { getSession } from "next-auth/react";
import { stripe } from "services/stripe";
// import { authOptions } from "./auth/[...nextauth]";

export default async (req: NextApiRequest, res: NextApiResponse) => {
    if(req.method == 'POST') {
        console.log(req, res);
        const session = await getSession({ req });
        console.log(req.cookies, session);
        // console.log(session);

        if(!session) return;

        const stripeCustomer = await stripe.customers.create({
            email: session.user.email,
        })

        const stripeCheckoutSession = await stripe.checkout.sessions.create({
            customer: stripeCustomer.id,
            payment_method_types: ['card'],
            billing_address_collection: 'required',
            line_items: [
                { price: 'price_1Kn2z8HXoO2e9eo5NaPFzRV1', quantity: 1 }
            ],
            mode: 'subscription',
            allow_promotion_codes: true,
            success_url: process.env.STRIPE_SUCCESS_URL,
            cancel_url: process.env.STRIPE_CANCEL_URL
        });

        return res.status(200).json({ sessionId: stripeCheckoutSession.id });
    } else {
        res.setHeader('Allow', 'POST');
        res.status(405).end('Method not allowed');
    }
}

[...nextauth].js代码

import { query as q } from 'faunadb';

import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";

import { Fauna } from "services/fauna";

export const authOptions = {
    providers: [
        GithubProvider({
            clientId: process.env.GITHUB_ID,
            clientSecret: process.env.GITHUB_SECRET,
            authorization: { params: { scope: 'read:user' } }
        }),
    ],
    callbacks: {
        async signIn({ user, account, profile }) {
            const { email } = user;

            try {
                await Fauna.query(
                    q.If(
                        q.Not(
                            q.Exists(
                                q.Match(
                                    q.Index('user_by_email'), 
                                    q.Casefold(user.email)
                                )
                            )
                        ),
                        q.Create(
                            q.Collection('users'),
                            { data: { email } }
                        ),
                        q.Get(
                            q.Match(
                                q.Index('user_by_email'), 
                                q.Casefold(user.email)
                            )
                        )
                    )
                );

                return true;

            } catch (error) {
                console.log(error);
                return false;
            }
        }
    }
};
export default NextAuth(authOptions);

问题排查与解决

核心问题1:服务端API错误使用客户端getSession方法

你在subscribe.ts中导入的next-auth/react下的getSession是客户端专属方法,无法在服务端API路由中直接调用。服务端必须使用next-auth/next下的服务端会话获取方法。

核心问题2:未传入authOptions配置

服务端获取会话时,必须传入authOptions来验证Cookies中的会话信息,你之前注释了相关导入和调用,这是会话返回null的关键原因。

修复步骤:

  1. 修改subscribe.ts的会话获取逻辑:
import { NextApiRequest, NextApiResponse } from "next";
import { unstable_getServerSession } from "next-auth/next"; // 改用服务端方法
import { stripe } from "services/stripe";
import { authOptions } from "./auth/[...nextauth]"; // 导入authOptions配置

export default async (req: NextApiRequest, res: NextApiResponse) => {
    if(req.method == 'POST') {
        // 传入req、res和authOptions获取会话
        const session = await unstable_getServerSession(req, res, authOptions);
        console.log(req.cookies, session);

        if(!session) {
            return res.status(401).json({ error: "未授权访问" }); // 返回明确的未授权状态
        }

        // 剩余Stripe逻辑保持不变
        const stripeCustomer = await stripe.customers.create({
            email: session.user.email,
        })

        const stripeCheckoutSession = await stripe.checkout.sessions.create({
            customer: stripeCustomer.id,
            payment_method_types: ['card'],
            billing_address_collection: 'required',
            line_items: [
                { price: 'price_1Kn2z8HXoO2e9eo5NaPFzRV1', quantity: 1 }
            ],
            mode: 'subscription',
            allow_promotion_codes: true,
            success_url: process.env.STRIPE_SUCCESS_URL,
            cancel_url: process.env.STRIPE_CANCEL_URL
        });

        return res.status(200).json({ sessionId: stripeCheckoutSession.id });
    } else {
        res.setHeader('Allow', 'POST');
        res.status(405).end('Method not allowed');
    }
}
  1. 版本兼容性检查:

    • 若使用NextAuth v4+,unstable_getServerSession已稳定,可直接替换为getServerSession(导入路径不变)。
    • 确认authOptions的导入路径与你的文件结构匹配,避免路径错误。
  2. 优化未授权处理:
    原代码中if(!session) return;会导致请求无响应,改为返回401状态码,方便前端处理未授权场景。


内容的提问来源于stack exchange,提问作者Lucas Marthins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:15:51