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

NextAuth.js登录后重定向前存储Cookie问题

NextAuth.js登录重定向前设置Cookie失败的解决方案

核心问题原因

你当前在session回调中设置Cookie的方式存在两个关键问题:

  • js-cookie是纯客户端库,若session回调在服务端执行(比如SSR场景),完全无法操作浏览器Cookie;
  • 即使在客户端执行,登录后的重定向操作可能比Cookie设置的异步操作更快完成,导致Cookie还没写入就跳转了。

正确解决方案:在服务端回调中通过响应头设置Cookie

NextAuth的signIn回调在登录流程的服务端环节执行,此时可以直接通过res对象的响应头设置Cookie,确保在重定向到前端前,Cookie已经被浏览器接收。

修改后的完整代码

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import FacebookProvider from 'next-auth/providers/facebook';
import { serialize } from 'cookie'; // Next.js内置的Cookie序列化工具

export default NextAuth({
    providers: [
        GoogleProvider({
            clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
            clientSecret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET,
            authorization: {
                params: { scope: "profile email" }
            }
        }),
        FacebookProvider({
            clientId: process.env.NEXT_PUBLIC_FACEBOOK_APP_ID,
            clientSecret: process.env.NEXT_PUBLIC_FACEBOOK_APP_SECRET,
        }),
    ],
    session: { jwt: true },
    callbacks: {
        async signIn({ user, account, profile, req, res }) {
            try {
                const response = await fetch('url', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        first_name: profile.given_name,
                        last_name: profile.family_name,
                        email: profile.email,
                        country_id: "13",
                        ip: '127.0.0.1',
                        platform: 'web',
                        provider: account.provider,
                        social_user_id: profile.sub,
                    }),
                });

                if (response.status === 200) {
                    const data = await response.json();
                    const accessToken = data.response.data.token;
                    user.accessToken = accessToken;
                    user.profile = profile;

                    // 服务端通过响应头设置Cookie
                    const cookieOptions = {
                        maxAge: 30 * 24 * 60 * 60, // 30天有效期
                        path: '/', // 全站可访问
                        secure: process.env.NODE_ENV === 'production', // 生产环境启用HTTPS安全Cookie
                        sameSite: 'strict', // 严格同源策略,防止CSRF
                        httpOnly: true, // 可选:若前端无需JS读取,开启后更安全(防XSS)
                    };
                    // 序列化Cookie并写入响应头
                    res.setHeader('Set-Cookie', serialize('accessToken', accessToken, cookieOptions));

                    return true;
                }
            } catch (error) {
                console.error('Error signing in', error);
                return false;
            }
        },
        async jwt({ token, user, account }) {
            if (user) {
                token.accessToken = user.accessToken; // 改用自己后端返回的token,而非第三方平台的accessToken
                token.user = user;
            }
            return token;
        },
        async session({ session, token }) {
            session.accessToken = token.accessToken;
            session.user = token.user;
            // 此处无需再设置Cookie,已在signIn服务端环节完成
            return session;
        },
        async redirect() {
            return `/my-account`;
        },
    },
});

关键细节说明

  1. 用内置工具序列化Cookie:使用Next.js自带的cookie库的serialize方法,避免手动拼接Cookie字符串时出现格式错误;
  2. 服务端设置响应头:在signIn回调的服务端环境中,通过res.setHeader直接写入Set-Cookie响应头,确保浏览器在接收重定向响应前就完成Cookie存储;
  3. 安全配置优化:
    • 生产环境开启secure,仅在HTTPS下传输Cookie;
    • 开启sameSite: 'strict',防止跨站请求伪造;
    • 可选开启httpOnly,禁止前端JS读取Cookie,大幅降低XSS攻击风险(若前端无需直接使用该token,建议开启);
  4. 修正token来源:之前的jwt回调错误使用了第三方平台的account.accessToken,现在改为使用自己后端返回的user.accessToken,符合业务需求。

验证方法

登录成功后,打开浏览器开发者工具的Application标签(Chrome),查看对应域名下的Cookies列表,确认accessToken是否存在;同时检查登录回调接口的响应头,确认包含Set-Cookie字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:05:57