当前端和后端位于不同域时,在前端设置会话 cookie 的问题

问题描述 投票:0回答:0

我正在开发一个全栈项目,该项目有一个 React + Next.js 前端和一个使用 Node.js 构建的 REST API 作为后端。身份验证系统将使用 passportjs 和 passport-google-oauth20 策略来实现。我选择使用会话 cookie 而不是 JWT 令牌来进行用户身份验证。据我所知,此过程中的一个步骤是在前端设置一个 cookie 来存储会话数据。在学习了一些教程之后,我构建了一个可以在我的本地主机上运行的前端 + 后端。然而,cookie 并没有在部署中设置,我的前端托管在 Vercel (https://vercel.com) 上,我的后端托管在渲染 (https://render.com) 上。

相信问题出在 passport.js 上,我花了几个小时解析我的后端代码并寻找不同的解决方案。最后,我偶然发现了“网络”选项卡(我应该先检查一下)并发现了这个:

set-cookie header in network tab

如您所见,有人警告我“此尝试通过 Set-Cookie 设置 cookie 标题被阻止,因为它的域 属性对于当前无效 主机网址。”

经过一些研究,我发现一些 StackOverflow 答案提到了“子域”的使用。据我了解,将后端和前端置于同一域的不同子域是解决此问题的唯一方法。我对这个假设是否正确?我有没有办法在我的前端存储 cookie 说:https://project_name.vercel.app,从我的后端发送在https://project_name.onrender.com?

这是我的 index.ts 的代码:

import express from "express";
import dotenv from "dotenv";
import cors from "cors";
import passport from "passport";
import { errorHandler } from "./middleware/error.middleware";
import session from "express-session";
import MongoStore from "connect-mongo";

import { initDB } from "./config/initDB";
import { initPassport } from "./config/initPassport";
import authRouter from "./routers/auth.router";
import mongoose from "mongoose";
import opportunityRouter from "./routers/opportunity.router";
import cookieParser from "cookie-parser";

const app = express();
dotenv.config();

app.use(
  cors({
    origin: process.env.FRONTEND_BASE_URL,
    credentials: true,
  })
);

app.set("trust proxy", 1);

// Not required as cors package takes care of it
// app.use((req, res, next) => {
//   res.header("Access-Control-Allow-Origin", "*");
//   res.header("Access-Control-Allow-Headers", "*");
//   res.header("Access-Control-Allow-Credentials", "true");
//   next();
// });

app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

initDB();

const mongoStore = MongoStore.create({
  client: mongoose.connection.getClient(),
  collectionName: "sessions",
  autoRemove: "interval",
  autoRemoveInterval: 1, // In minutes
});

app.use(
  session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
    store: mongoStore,
    cookie: {
      maxAge: 1000 * 60 * 60 * 24, // Session expiration time in milliseconds
      sameSite: "none",
      secure: true,
      httpOnly: true,
      domain: process.env.DOMAIN, //Set to .vercel.app (frontend)
    },
  })
);

app.use(passport.initialize());
app.use(passport.session());

initPassport();

app.use("/auth", authRouter);
app.use("/opportunity", opportunityRouter);

app.use(errorHandler);

const port = process.env.PORT || 3001;
app.listen(port, () => {
  console.log(`Backend server is running on port ${process.env.PORT}`);
});

node.js cookies passport.js session-cookies setcookie
© www.soinside.com 2019 - 2024. All rights reserved.