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

Next.js 13.4 App目录下next-auth CredentialsProvider无法设置后端Cookie

Next.js 13.4 + NextAuth:迁移后无法设置外部后端返回的Cookie

我有一个依赖外部后端做身份认证的项目,登录成功后后端会返回Cookie,登录页使用了'use client'指令。

在Next.js 13.2版本时,位于\pages\api\auth\[...nextauth].js的NextAuth代码可正常工作,Cookie能正确设置,代码如下:

import NextAuth from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'

import { postAuthLogin } from '@/lib/requests/auth'

export const options = (req, res) => {
  return {
    providers: [
      CredentialsProvider({
        name: 'credentials',
        credentials: {
          username: { label: "Username", type: "text", placeholder: "jsmith", value: "" },
          password: { label: "Password", type: "password", value: "" }
        },
        async authorize(credentials) {
          try {
            const login_resp = await postAuthLogin(
              {
                "email": credentials.username,
                "password": credentials.password
              });

            const user = login_resp.data.user;
            const cookies = login_resp.headers['set-cookie']

            res.setHeader('Set-Cookie', cookies)
            return user;

          } catch (e) {
            throw new Error(e?.response?.data?.detail || "There was an error on user authentication");
          }
        }
      })
    ],
    pages: {
      signIn: '/signin',
      error: '/error', 
    },
    callbacks: {
      async signIn({ user, account, profile, email, credentials }) {
        return true
      },
      async redirect({ url, baseUrl }) {
        return Promise.resolve(baseUrl)
      }
    },
  }
}

const nextAuth = (req, res) => {
  return NextAuth(req, res, options(req, res))
}

export default nextAuth

升级到Next.js 13.4.10版本后,出现了setHeader is not a function错误。为适配Next.js 13.4,我将NextAuth文件迁移到\app\api\auth\[...nextauth]\route.js路径,并修改了代码:

import axios from "axios";
import NextAuth from "next-auth";

import CredentialsProvider from "next-auth/providers/credentials";
import { NextResponse } from "next/server";


export const next_options = (req, res) => {
    return {
        providers: [
            CredentialsProvider({
                name: 'Credentials',
                credentials: {
                    username: { label: "Username", type: "text", placeholder: "jsmith", value: "" },
                    password: { label: "Password", type: "password", value: "" }
                },
                async authorize(credentials) {
                    try {
                        const login_resp = await postAuthLogin(
                            {
                                "email": credentials.username,
                                "password": credentials.password
                            });

                        const user = login_resp.data.user;
                        const backend_cookies = login_resp.headers['set-cookie']

                        const newHeaders = new Headers(req.headers)
                        newHeaders.append('Set-Cookie', backend_cookies)

                        const response =  NextResponse.next({
                            request: {
                              headers: newHeaders,
                            },
                          });

                        const a = newHeaders.get('Set-Cookie')
                        console.log("NewHeader", a)
                        
                        return user;

                    } catch (e) {
                        console.log('Error', e, e?.response?.data)
                        throw new Error(e?.response?.data?.detail || "There was an error on user authentication");
                    }
                }
            })
        ],
        pages: {},
        callbacks: {
            async signIn({ user, account, profile, email, credentials }) {
                return true
            },
            async redirect({ url, baseUrl }) {
                return Promise.resolve(baseUrl)
            }
        },
    }
}

export { nextAuth as GET, nextAuth as POST };

export const postAuthLogin = async (body) => {
    const res = await axios.post("http://localhost:8001/auth/login", body, {
        withCredentials: true,
    })
    return res
}

const nextAuth = (req, res) => {
    return NextAuth(req, res, next_options(req, res))
}

修改后无报错,但Cookie仍未成功设置。

期望行为

  • 已认证用户的请求能携带设置的Set-Cookie头
  • 浏览器开发者工具的「Application」标签的「Cookies」中能看到这些Cookie
  • 外部后端的所有安全端点都能接收到这些Cookie

注:后端已通过充分测试,在Next.js 13.2的旧代码下运行正常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:32:04