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

使用unstable_getServerSession保护NextAuth API时Session为null

NextAuth API路由无法获取Session问题排查与解决

登录状态下,pages/dashboard/index.js的getServerSideProps能正常获取Session,但调用/api/profile接口时,unstable_getServerSession返回null,导致接口返回401,Dashboard无法展示内容。已按照官方文档配置API路由权限,但未生效。


相关代码

pages/api/profile.js

import prisma from "../../../lib/prisma";
import { unstable_getServerSession } from "next-auth/next";
import { authOptions } from "../auth/[...nextauth]";

export default async function handler(req, res) {
  const session = await unstable_getServerSession(req, res, authOptions);
  console.log("SESSION", session); // 此处打印"null"
  if (!session) {
    return res.status(401).json("Not authorized");
  }
 try {
      const user = await prisma.user.findUnique({
        where: { email: session.user.email },
      });
      return res.status(200).json(user);
    } catch (error) {
      console.error(error);
      return res
        .status(503)
        .json(
          "Our server is not able to process the request at the moment, please try again later!"
        );
    }
}

pages/api/auth/[...nextauth].js

import NextAuth from "next-auth";
import CognitoProvider from "next-auth/providers/cognito";
import prisma from "../../../lib/prisma";

export const authOptions = {
  providers: [
    CognitoProvider({
      clientId: process.env.CLIENTID_NEXTAUTH,
      issuer: process.env.COGNITO_ISSUER,
      clientSecret: process.env.CLIENTSECRET_NEXTAUTH,
    }),
  ],
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60,
    updateAge: 24 * 60 * 60,
  },
  callbacks: {
    async jwt({ token, account }) {
      if (account) {
        token.accessToken = account.access_token;
      }
      return token;
    },
    async session({ session, token }) {
      const user = await prisma.user.findUnique({
        where: { email: session?.user?.email },
      });

      if (!user) throw new Error("User not found in the database.");

      const mySession = {
        ...session,
        accessToken: token.accessToken,       
        email: user.email,
      };
      return mySession;
    },
  },
};

export default NextAuth(authOptions);

pages/dashboard/index.js

import axios from "axios";
import React, { useState } from "react";
import { getSession, useSession } from "next-auth/react";

const Dashboard = (props) => {
    let { data: session, status } = useSession();

    if (status === "loading") {
    return <p>Loading...</p>;
  }

  if (status === "unauthenticated") {
    window.location.reload();
  }

  return (
    <p>
     {props.userInfo.name}
    </p>
  );
};

export default Dashboard;

export async function getServerSideProps(context) {
  const session = await getSession(context);

  if (!session) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  }

  console.log("SESSION IN INDEX", session); // 此处能正常打印Session
  const userInfo = await axios.get(
    `${process.env.BASE_URL}/api/profile?email=${session.email}`
  );
  

  return {
    props: {
      session,
      userInfo: userInfo.data ? userInfo.data : null,     
    },
  };
}

问题原因与解决方案

核心原因

  1. API请求未携带Session凭证:getServerSideProps中用axios调用/api/profile时,默认不会自动携带NextAuth的Session Cookie,导致API路由无法识别用户身份。
  2. Session回调逻辑缺陷:session回调依赖session.user.email,若该值为空会触发查询失败;同时自定义Session结构时未保留标准user字段,可能导致Session解析异常。

修复步骤

1. 给API请求手动传递Cookie

修改getServerSideProps中的axios请求,从context中获取Cookie并携带:

export async function getServerSideProps(context) {
  const session = await getSession(context);

  if (!session) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  }

  console.log("SESSION IN INDEX", session);
  // 携带请求Cookie,让API路由识别Session
  const userInfo = await axios.get(`${process.env.BASE_URL}/api/profile`, {
    headers: {
      Cookie: context.req.headers.cookie || ""
    }
  });

  return {
    props: {
      session,
      userInfo: userInfo.data ? userInfo.data : null,     
    },
  };
}
2. 优化Session回调逻辑

确保从token中获取可靠的用户标识,同时保留标准Session结构:

// pages/api/auth/[...nextauth].js
callbacks: {
  async jwt({ token, account, user }) {
    // 首次登录时保存用户邮箱到token
    if (user) {
      token.email = user.email;
    }
    if (account) {
      token.accessToken = account.access_token;
    }
    return token;
  },
  async session({ session, token }) {
    // 从token获取邮箱,避免依赖session.user.email
    const user = await prisma.user.findUnique({
      where: { email: token.email },
    });

    if (!user) throw new Error("User not found in the database.");

    // 保留标准session.user结构,避免解析异常
    return {
      ...session,
      accessToken: token.accessToken,
      user: {
        ...session.user,
        email: user.email,
        name: user.name
      }
    };
  },
},
3. 额外检查项
  • 确认环境变量NEXTAUTH_URL已正确配置(生产环境需匹配域名),NextAuth依赖该值生成正确的Cookie。
  • 检查浏览器DevTools的Application标签,确认存在next-auth.session-token Cookie,且域名与当前站点匹配。
  • 验证Cognito的issuer格式是否正确,应为https://cognito-idp.<region>.amazonaws.com/<userPoolId>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:16:23