.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
相关产品推荐
相关产品推荐

