Next.js 13.4 App目录下next-auth CredentialsProvider无法设置后端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
相关产品推荐
相关产品推荐

