Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express JS/ Node JS : Browsers are not setting cookie when secure=true, sameSite: 'none'

it sets the cookie if I run the server locally, but when it is hosted online :

  1. If secure=false, sameSite: 'none' then I get the following error

Cookie “connect.sid” will be soon rejected because it has the “sameSite” attribute set to “none” or an invalid value, without the “secure” attribute. To know more about the “sameSite“ attribute, read https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite

then I tried with secure=true

  1. if secure=true, sameSite: 'none' then I know it's supposed to work,

it works and the cookies are set when the server is hosted locally. But when it is hosted in heroku the cookie are not set, and I get no error.

It seems as if the client website is not secure but it shows https in the url box

What am I doing wrong here?

session config:

router.use(
    session({
        cookie: {
            secure: true,
            maxAge: 86400,
            sameSite: "none",
        },
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
    })
);

note : I have already enabled cors with credentials set to true The cookies tab was empty in the XHR cookies tab Front-end and Back-end are hosted separately in heroku XMLHttpRequest is used to send post request with withCredentials set to true.

XHRPOSThttps://sih-drs-prototype-backend-2.herokuapp.com/api/outrages/login [HTTP/1.1 200 OK 1625ms]

POST https://sih-drs-prototype-backend-2.herokuapp.com/api/outrages/login Status200 OK VersionHTTP/1.1 Transferred367 B (2 B size)

Access-Control-Allow-Credentials
    true
Access-Control-Allow-Origin
    https://tempautocomplete.herokuapp.com
Connection
    keep-alive
Content-Length
    2
Content-Type
    application/json; charset=utf-8
Date
    Sun, 12 Jul 2020 14:06:42 GMT
Etag
    W/"2-vyGp6PvFo4RvsFtPoIWeCReyIC8"
Server
    Cowboy
Vary
    Origin
Via
    1.1 vegur
X-Powered-By
    Express
    
Accept
    */*
Accept-Encoding
    gzip, deflate, br
Accept-Language
    en-US,en;q=0.5
Connection
    keep-alive
Content-Length
    46
Content-Type
    application/json;charset=UTF-8
Host
    sih-drs-prototype-backend-2.herokuapp.com
Origin
    https://tempautocomplete.herokuapp.com
Referer
    https://tempautocomplete.herokuapp.com/static/
User-Agent
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0
like image 968
Prashan Avatar asked Jul 12 '20 14:07

Prashan


People also ask

How do you set the SameSite none and secure cookie?

SameSite=None requires Secure The warning appears because any cookie that requests SameSite=None but is not marked Secure will be rejected. To fix this, you will have to add the Secure attribute to your SameSite=None cookies. A Secure cookie is only sent to the server with an encrypted request over the HTTPS protocol.

How do I turn on SameSite cookies?

Enable the new SameSite behavior If you are running Chrome 91 or newer, you can skip to step 3.) Go to chrome://flags and enable (or set to "Default") both #same-site-by-default-cookies and #cookies-without-same-site-must-be-secure. Restart Chrome for the changes to take effect, if you made any changes.

Is it safe to set SameSite to none?

The none value won't give any kind of protection. The browser attaches the cookies in all cross-site browsing contexts. The default value of the SameSite attribute differs with each browser, therefore it is advised to explicitly set the value of the attribute.

How do I fix my SameSite attribute?

Resolve this issue by updating the attributes of the cookie: Specify SameSite=None and Secure if the cookie is intended to be set in cross-site contexts. Note that only cookies sent over HTTPS may use the Secure attribute.


2 Answers

The problem is not with expres-session, It does its job. The browsers are not allowing cookies when the response comes from a 3rd party domain.


if you are looking for a workaround try this npm package : should-send-same-site-none https://www.npmjs.com/package/should-send-same-site-none


to be clear, the browser is not rejecting the cookies. Instead the cookies are stored in the name of the 3rd party domain name from which the response is sent.

It works perfectly fine when hosting locally since the request and the response would be from the same domain (localhost)

like image 80
Prashan Avatar answered Oct 21 '22 16:10

Prashan


The settings, as posted in the original question are OK, only one thing was missing since Heroku might be using a proxy. I ran into the same problem and when I added:

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

The Set-Cookie header was finally sent from the Express server, hosted on Heroku to the browser.

like image 38
Shaul Amran Avatar answered Oct 21 '22 16:10

Shaul Amran