2

I am using express in the back end with react in the front end. I am using cors to fetch user details from passport.js GoogleOAuth. I am using Heroku to host the front end and the back end in two different domains. The request in the client looks like this:

fetchAuthUser = async () => {
    const metadata = {
      headers : {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      },
      referrerPolicy: "strict-origin-when-cross-origin",
      body: null,
      method: "GET",
      mode: "cors",
      credentials: "include"
    }
    
    const response = await fetch(Env.backend_host +'/authenticate_google/api/current_user', metadata).catch((err) => {
        console.log(err)
    });

    console.log(response);

    if (response && response.data) {
      this.setState({user: eval(response.data)}, () => {this.loadPages()});
    }
  }

and the server is currently set up in the following way:

The cookies is set like this,

router.use(
  cookieSession({
    maxAge: 30 * 24 * 60 * 60 * 1000, // sets cookie to expire in 30 days (converted to milliseconds)
    keys: ["trialkey"],
    sameSite: "lax",
  })
);

The get response is the following

router.get("/api/current_user", cors({ origin: "https://energycast-front.herokuapp.com", methods: ['GET','POST','OPTIONS'], credentials: true, preflightContinue: true}), (req, res) => {

    console.log("User:" +req.user)

    res.json(req.user);
 
  });

The problem does not seem to be cors related, however when observing the request, I see that no cookies are being sent. This is strange because I have set credentials "include".

Nota bene, the console is logging the "User" to be undefined on the server itself.

Any help will be appreciated.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Juan
  • 51
  • 1
  • 7

2 Answers2

2

I have figured out what went wrong, the problem was in cookie-session. When the cookie was set to sameSite = 'none', the network tool would pick it up and return the error that secure had to be set to true. However, after setting secure equal to true, the network debugging tool reverted into saying that samesite was set to "Lax" and that the cookies could not be sent.

I have thus switched to express-cookie package:

router.set('trust proxy', 1) // trust first proxy
router.use(
  session({
    secret: SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: { 
      secure: true,
      sameSite: "none"
    }
  })
);
Juan
  • 51
  • 1
  • 7
0

Cookies with SameSite=Lax are blocked if the request is made from a different site and is not initiated by a top-level navigation (but by a fetch statement).

Try using sameSite: "None".

The cookie might also be blocked because it falls foul of the third-party cookie settings in your browser.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • I have tried using sameSite: "None" with the additional secure tag but still had no luck. – Juan Aug 11 '21 at 06:31
  • @JuanCarlosBoschero, do the browser developer tools tell you why the cookie was blocked? Chrome DevTools > Network > Cookies contains very detailed information, for example. – Heiko Theißen Aug 11 '21 at 08:47
  • Thank you very much for the insight, I have looked into the network tag on the front end and the cookies were highlighted yellow stating that the "Cookie didn't specify a SameSite so it was set to Lax by default". However I currently have the code set like this: `router.use( cookieSession({ maxAge: 30 * 24 * 60 * 60 * 1000, keys: ["trialkey"], sameSite: "none", secure: true }) );` – Juan Aug 13 '21 at 09:12
  • Perhaps `cookie-session` does not support `sameSite`? It's not mentioned on https://www.npmjs.com/package/cookie-session#cookie-options – Heiko Theißen Aug 13 '21 at 09:26
  • I tried looking into it but it appears is should work since the site you have shown was published two years ago and a similar question was asked a year ago with the `sameSite` tag, https://stackoverflow.com/questions/63680921/i-cant-set-the-samesite-attribute-of-the-cookie-to-none-in-nodejs-express. I have also looked to see if I have the problem in the thread by rewriting my code to also have the `httpOnly:true` set to true but still nothing. – Juan Aug 13 '21 at 15:45