4

I've been trying to fix the new CORS issue thrown by Google Chrome via express-session but it doesn't seem to fix it. Specifically, this error:

A cookie associated with a cross-site resource at http://plant-app-test.herokuapp.com/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

My current stack is Node.js, Express.js, and Passport.js for authentication. You may see the configurations below:

  • app.js

require("dotenv").config();

const path = require("path");
const cors = require("cors");
const logger = require("morgan");
const helmet = require("helmet");
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");

const app_name = require("./package.json").name;
const debug = require("debug")(
  `${app_name}:${path.basename(__filename).split(".")[0]}`
);

const app = express();

// CORS setup
app.use(
  cors({
    credentials: true,
    preflightContinue: true,
    optionsSuccessStatus: 200,
    origin: process.env.REACT_APP_CLIENT_POINT,
    allowedHeaders: ["Content-Type", "Authorization"],
    methods: ["GET", "POST", "PUT", "HEAD", "PATCH", "DELETE"],
  })
);

// Middleware Setup
app.use(helmet());
app.use(logger("dev"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

require("./configs/db.config");
require("./configs/session.config")(app);
require("./configs/passport/passport.config.js")(app);

// Route setup
app.use("/", require("./routes/index"));
app.use("/auth", require("./routes/auth"));
app.use("/app", require("./routes/application"));

module.exports = app;
  • session-config.js

const session = require("express-session");
const mongoose = require("mongoose");
const MongoStore = require("connect-mongo")(session);
const cookieParser = require("cookie-parser");

module.exports = (app) => {
  app.use(
    session({
      secret: process.env.SESS_SECRET,
      name: "sessionID",
      cookie: {
        sameSite: "none",
        secure: true,
      },
      resave: false,
      saveUninitialized: false,
      store: new MongoStore({
        mongooseConnection: mongoose.connection,
        ttl: 60 * 60 * 24 * 1000,
      }),
    })
  );
};
  • passport-config.js

const passport = require("passport");

require("./serializers.config");
require("./local-strategy.config");
require("./google-strategy.config");
require("./facebook-strategy.config");

module.exports = (app) => {
  app.use(passport.initialize());
  app.use(passport.session());
};
  • serializers-config.js

const passport = require("passport");
const User = require("../../models/User.model");

passport.serializeUser(function (user, done) {
  done(null, user._id);
});

passport.deserializeUser(async function (id, done) {
  await User.findById(id, function (err, user) {
    if (!err) done(null, user);
    else done(err, null);
  });
});

I've tried several different configurations on the session cookie and it runs well on my dev. environment (both located on HTTP://localhost but with different ports). Can someone please help as this doesn't allow me to persist the session for the users and leverage their id stored on the cookie for my workflows?

Thank you!

  • It might be more helpful if you also posted what headers are being sent to the server so we can see why the cookie is being blocked. Also the URL you posted doesn't have a proper https cert, that could be part of the issue since you provided: ` secure: true,`. This will work on localhost but fail when hosted – Kyle Mills Sep 09 '20 at 19:40

2 Answers2

1

For my heroku app and a very similar situation, I fixed it by adding proxy : true, to the express-session configuration. I believe this enabled the SSL communication required by secure: true.

Carson
  • 36
  • 2
0

try to use cookieParser first then enabled cors -I can't really understand why but I believe in express ordering maters. After that try to inject the session "app.use(injectSession)" here you might need to tweak your session config code to suit this style. I don't think you need to import cookieParser again in your session-config file, maybe it overrides your previous configs.

That Guy Kev
  • 386
  • 2
  • 10