6

I have a Node.js, Angular app. (Node.js server written in TypeScript). Node.js Server is running on an Amazon EC-2 instance, the Angular client is on another server.

For the login session, I use express-session. I am not using cookies in the app, so I think the problem is with the express-session cookies. On Firefox it works properly, but with Google Chrome (80.0.3987.149) it not works: Chrome doesn't save the session (so I can not leave the login page) and warns:

A cookie associated with a cross-site resource at http://addressof.myserverapp.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.

In Node.js server I set the express-sessions this way:

import cookieParser from 'cookie-parser';
app.use(cookieParser(secret));

app.use(session({
    secret: secret,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: false,
        maxAge: null,
        secure: true,
        sameSite: 'none'
    },
    store: sessionStore // MySqlStore - express-mysql-session
}));

I also tried to solve the problem with this code snippet (from https://github.com/expressjs/session/issues/725#issuecomment-605922223)

Object.defineProperty(session.Cookie.prototype, 'sameSite', {
    // sameSite cannot be set to `None` if cookie is not marked secure
    get() {
        return this._sameSite === 'none' && !this.secure ? 'lax' : this._sameSite;
    },
    set(value) {
        this._sameSite = value;
    }
});

Server npm packages:

"cors": "^2.8.5",
"cookie-parser": "^1.4.5",
"express": "^4.17.1",
"express-mysql-session": "^2.1.3",
"express-session": "^1.17.0",
Npm version: 6.13.4
Node version: 12.16.1

I spent days with this problem to figure out what am I doing wrong...

ramana vv
  • 1,141
  • 11
  • 21
  • Can you include an example of the `Set-Cookie` header that is being sent? As you point out, it does look like `express-session` should support the `SameSite=None; Secure` attributes so we need to take a look at what's being sent and received. We have a more complete debugging guide here: https://www.chromium.org/updates/same-site/test-debug – rowan_m Apr 07 '20 at 10:11

1 Answers1

0

The issue here is that you are accessing the Website via HTTP, but the cookie secure setting is true, which means that it will only be sent via HTTPS.

If you set secure: false in the express-session cookie options, it will work:

import cookieParser from 'cookie-parser';
app.use(cookieParser(secret));

app.use(session({
    secret: secret,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: false,
        maxAge: null,
        // allow the cookie to be sent via HTTP ("true" means "HTTPS only)
        secure: false, 
        sameSite: 'none'
    },
    store: sessionStore
}));
david_p
  • 4,444
  • 1
  • 26
  • 22