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

.NET API的HttpOnly Cookie无法通过Next-Auth传递至前端的问题

问题描述
  • 直接从React前端调用.NET 6 API登录接口时,HttpOnly类型的RefreshToken Cookie可正常传递至前端并存储
  • 通过Next-Auth的authorize方法发起登录请求时,Cookie无法传递到前端;即使手动设置Set-Cookie响应头,后续前端通过Next-Auth调用API时也无法将Cookie传回.NET API
  • 需求:无需Next-Auth处理该Cookie,仅需保证Cookie能在.NET API ↔ Next-Auth ↔ 前端之间正确传递

解决方案

1. 在Next-Auth中正确转发Set-Cookie到前端

Next-Auth的authorize方法运行在服务器端,服务器端fetch收到的Set-Cookie不会自动传递给前端,需手动提取并添加到Next-Auth的响应头中,注意处理多Cookie场景:

const authOptions = (req, res) => ({
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials) {
        const loginResponse = await fetch(`https://localhost:7183/api/login`, {
          method: "POST",
          credentials: "include",
          body: JSON.stringify({
            Email: credentials.email,
            Password: credentials.password,
          }),
          headers: {
            "Accept": "application/json",
            "Content-Type": "application/json",
          },
        });

        // 提取所有Set-Cookie头(支持多Cookie场景)
        const setCookieHeaders = loginResponse.headers.getAll("set-cookie");
        if (setCookieHeaders.length > 0) {
          setCookieHeaders.forEach(cookie => {
            res.setHeader("Set-Cookie", cookie);
          });
        }

        if (!loginResponse.ok) {
          const errorData = await loginResponse.json();
          throw new Error(errorData.exception || "登录失败");
        }

        const user = await loginResponse.json();
        return user;
      },
    }),
  ],
  session: {
    strategy: "jwt", // 保持默认策略,无需Next-Auth处理自定义Cookie
  },
});

export default (req, res) => {
  return NextAuth(req, res, authOptions(req, res));
};

2. 配置Next.js允许凭证传递

在next.config.js中添加跨域凭证配置,确保前端与Next-Auth接口之间的Cookie传递:

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/api/auth/:path*',
        headers: [
          { key: 'Access-Control-Allow-Credentials', value: 'true' },
          { key: 'Access-Control-Allow-Origin', value: 'http://localhost:3000' }, // 匹配你的前端地址
          { key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT' },
          { key: 'Access-Control-Allow-Headers', value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' },
        ],
      },
    ];
  },
};

3. 前端调用API时通过代理转发Cookie

创建Next.js代理路由,将前端的Cookie传递给.NET API,并把API返回的Cookie再转发回前端:

// pages/api/proxy/[...path].js
export default async function handler(req, res) {
  const { path } = req.query;
  const targetUrl = `https://localhost:7183/api/${path.join('/')}`;

  // 提取前端请求中的Cookie
  const cookies = req.headers.cookie;

  const apiResponse = await fetch(targetUrl, {
    method: req.method,
    headers: {
      ...req.headers,
      'host': new URL(targetUrl).host, // 替换host头避免冲突
    },
    credentials: 'include',
    body: req.method !== 'GET' ? await req.text() : undefined,
  });

  // 转发.NET API返回的Set-Cookie到前端
  const setCookieHeaders = apiResponse.headers.getAll("set-cookie");
  if (setCookieHeaders.length > 0) {
    setCookieHeaders.forEach(cookie => {
      res.setHeader("Set-Cookie", cookie);
    });
  }

  // 转发API响应状态和内容
  res.status(apiResponse.status);
  res.setHeader('Content-Type', apiResponse.headers.get('Content-Type'));
  res.send(await apiResponse.text());
}

前端调用该代理路由(如/api/proxy/refresh-token)即可自动传递Cookie。

4. .NET API配置检查

确认以下配置无问题:

  • Cookie的Domain设置为localhost,Path设置为/
  • CORS配置已添加WithExposedHeaders("Set-Cookie")和AllowCredentials()
  • Cookie的Secure=true(仅HTTPS环境生效,本地开发需确保.NET和Next.js都启用HTTPS)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:15:26