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

部署Netlify后Passport.js无法在浏览器保存Cookie问题求助

MERN栈聊天应用部署Netlify后Google认证无法保存Cookie

我正在开发一款MERN栈聊天应用,用Passport.js实现Google OAuth2认证。本地环境下一切正常:能正常登录,用户信息也能存入MongoDB。但把前端部署到Netlify后,虽然登录流程能完成、用户数据也能写入数据库,但浏览器无法保存Session Cookie,导致后续请求无法识别已登录用户。


相关代码

passport.js(认证中间件)

import * as dotenv from "dotenv";
import passport from "passport";
import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import User from "./models/user.js";
dotenv.config();

passport.serializeUser((user, cb) => {
  cb(null, user.id);
});

passport.deserializeUser((id, cb) => {
  User.findById(id).then((user) => {
    cb(null, user);
  });
});

passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: process.env.GOOGLE_CALLBACK_URL,
    },
    function (accessToken, refreshToken, profile, cb) {
      console.log(" google strategy called");
      User.findOne({ googleId: profile.id }).then((currentUser) => {
        if (currentUser) {
          // 用户已存在
          console.log("user find one called");
          cb(null, currentUser);
        } else {
          // 创建新用户存入数据库
          new User({
            name: profile.displayName,
            googleId: profile.id,
            email: profile.emails[0].value,
            picture: profile.photos[0].value,
            membership: "free",
          })
            .save()
            .then((newUser) => {
              cb(null, newUser);
            });
        }
      });
    }
  )
);

index.js(后端入口文件)

dotenv.config();
const app = express();
app.use(
  cors({
    origin: "https://taupe-starburst-7fab32.netlify.app",
    methods: "GET,POST,PUT,DELETE",
    credentials: true,
  })
);
app.use(express.json());
Connection();
app.use(
  cookieSession({
    name: "session",
    keys: [process.env.SESSION_SECRET],

    // Cookie配置项
    domain: "https://taupe-starburst-7fab32.netlify.app",
    maxAge: 24 * 60 * 60 * 1000, // 24小时有效期
    secure: true,
    httpOnly: true,
    sameSite: "none",
  })
);
// 修复session.regenerate不存在的问题
app.use(function (request, response, next) {
  if (request.session && !request.session.regenerate) {
    request.session.regenerate = (cb) => {
      cb();
    };
  }
  if (request.session && !request.session.save) {
    request.session.save = (cb) => {
      cb();
    };
  }
  next();
});
app.use(passport.initialize());
app.use(passport.session());

app.use("/auth", router);

const server = app.listen(process.env.PORT || 5000, () =>
  console.log("server running")
);

auth.js(认证路由)

import express from "express";
import passport from "passport";

const router = express.Router();

// 登录成功回调
router.get("/login/success", (req, res) => {
  if (req.user) {
    res.status(200).json({
      success: true,
      message: "successfull",
      user: req.user,
    });
  } else {
    res.status(401).json({
      success: false,
      message: "Unauthorized: User is not logged in",
    });
  }
});

// 登录失败回调
router.get("/login/failed", (req, res) => {
  res.status(401).json({
    success: false,
    message: "failure",
  });
});

// Google认证入口
router.get(
  "/google",
  passport.authenticate("google", { scope: ["email", "profile"] })
);

// Google认证回调
router.get(
  "/google/callback",
  passport.authenticate("google", {
    successRedirect: process.env.CLIENT_URL,
    failureRedirect: "/login/failed",
  })
);

// 登出路由
router.get("/logout", (req, res) => {
  req.logout(function (err) {
    if (err) {
      return next(err);
    }
    res.redirect(`${process.env.CLIENT_URL}/login`);
  });
});

export default router;

React前端Login组件

function Login() {
  const google = () => {
    window.open(`${process.env.REACT_APP_API_URL}auth/google`, '_self');
  };
  return (
    <button type="button" onClick={google}>
      Login with Google
    </button>
  );
}

export default Login;

解决方案

1. 修正Cookie的domain配置

Cookie的domain不能填带HTTPS的完整域名,需改为不带协议的二级域名前缀格式:

// index.js中cookieSession配置修改
domain: ".taupe-starburst-7fab32.netlify.app",

浏览器Cookie规则要求domain必须是纯域名,前缀加.表示允许该域名下的所有子域名共享Cookie。

2. 确保后端部署在HTTPS环境

secure: true配置要求Cookie只能在HTTPS协议下传输,如果后端用的是HTTP服务,会直接导致Cookie无法设置。必须确保后端服务通过HTTPS访问。

3. 校验Google OAuth回调URL配置

在Google Cloud Console中,确认回调URL是后端的HTTPS地址(比如https://你的后端域名/auth/google/callback),且和代码中GOOGLE_CALLBACK_URL的环境变量值完全一致。

4. 前端请求携带Credentials

前端后续调用API(比如获取登录用户信息)时,必须在请求中添加credentials: 'include',否则浏览器不会自动携带Cookie:

// 示例:前端获取用户信息的请求
fetch(`${process.env.REACT_APP_API_URL}auth/login/success`, {
  credentials: 'include'
})
.then(res => res.json())
.then(data => console.log(data))

5. 配置Netlify响应头(可选)

如果Netlify有自定义重定向规则,可在项目根目录的netlify.toml中添加以下配置,确保Cookie相关头信息正常传递:

[[headers]]
  for = "/*"
  [headers.values]
    Access-Control-Allow-Credentials = "true"
    Access-Control-Allow-Origin = "https://taupe-starburst-7fab32.netlify.app"

内容的提问来源于stack exchange,提问作者Sajib Hossain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:25:26