Search code examples
node.jsexpress

"Attemp to set a cookie via a Set-cookie header was blocked" Problem. Stack (ExpressJS, ReactJS, PassportJS)


I'm implementing Google Authentication with Passport JS. Everything works fine on localhost, but I have a problem in production.

My backend is deployed on render.com My frontend is deployed on vercel.app

Cookies are not set on the frontend due to This attempt to set a cookie via a Set-cookie header was blocked because its Domain attribute was invalid with regards to the current host url

Here are my express-session configs:

const domain = process.env.DOMAIN;

domain is gotten from render.com environment variables: DOMAIN = review-website-mu.vercel.app

Setting cookies configs programmatically:

if (domain) cookiesConfigs = {
        domain: domain,
        sameSite: 'none', 
        secure: false
    }

Setting session configs:

app.use(session({
    secret:'review-website',
    resave: false,
    saveUninitialized: false,
    store: new sessionStore({db: 'sessions.db', dir: './'}),
    cookie: cookiesConfigs
}));

Here's the problem:

error while setting cookies

My domain: my domain

setCookie header

empty application cookies storage

How can I fix it and make my app set cookies on the front side?

The domain name is exactly the same as domain of the front-end, but nevertheless it doesn't work


Solution

  • So, after hours researching this question, I came up with the next info:

    According to the RFC 6265 HTTP State Management Mechanism and exactly 4.1.2.3 "The Domain Attribute":

    [...] The user agent will reject cookies unless the Domain attribute
          specifies a scope for the cookie that would include the origin
          server.
    
    [...]  For example, the user agent will accept a cookie with a
           Domain attribute of "example.com" or of "foo.example.com" from
           foo.example.com, but the user agent will not accept a cookie with a
           Domain attribute of "bar.example.com" or of "baz.foo.example.com".
    
    [...] NOTE: For security reasons, many user agents are configured to reject
          Domain attributes that correspond to "public suffixes".
    

    Firts step was to host my frontend and backend both on the same hosting (render.com), but that did not work after all.

    Firstly, because my front-side and back-side of the application are on different subdomains, and this does not match the quote above. (So it would work, if front-end was mysite.com and backend was api.mysite.com, but not frontend.mysite.com and api.mysite.com).

    Secondly, onrender.com is in the Public Suffix List, so you can not set cookies on the site via the domain attribute whether this domain is in that list. The solution here would be to buy your own custom domain and set it according to the point I have written above.

    Finally, my solution was just to omit the domain attribute in cookies configs, but to leave Samesite: 'none' and Secure attributes. I still don't see cookies on my front end cookies storage but it works somehow, though.

    if (domain) cookiesConfigs = {
            sameSite: 'none', 
            secure: true (or false, it doesn't matter here)
        }