8

I am authenticating against an OIDC service using Passport.js with the OAuth2Strategy strategy. The application makes some cross-domain requests to services that need the connect.sid cookie that is set by Passport. Chrome is promising to stop supporting these requests unless the SameSite attribute of the cookie is set to "Lax".

I'm not sure how to do that as the setting of the cookie is internal to Passport. Any suggestions? Below is the relevant function call that lives in the callback route given to the OIDC service.

  passport.authenticate("oauth2", function (err, user, info) {
    if (err) {
      req.flash('error', err);
      res.redirect('/login_error/');
    }
    else if (!user) {
      req.flash('error', 'Unable to locate user account.');
      res.redirect('/login_error/');
    }
    else {
      req.logIn(user, (err) => {
        if (err) { return next(err); }
        return res.redirect('/user_profile/);
      });
    }
  })(req, res, next);
sean_x
  • 81
  • 3
  • 1
    The upcoming Chrome changes will mark cookies as `SameSite=Lax` by default unless otherwise stated, so if you're not relying on cross-site POST requests this should continue working. What backend service are you using? It may be possible to reach out and get them to update their cookies. – rowan_m Dec 07 '19 at 23:40
  • Thanks for the clarification, Rowan -- much appreciated. I'm using Express.js on the backend. – sean_x Dec 09 '19 at 15:17
  • @sean_x Did you get any solution for this? – Sarath Sasi Aug 26 '20 at 09:35

1 Answers1

1

Answer: Try using href. Or set-up proxy on the client app to the server app.

I had faced the same issue. Have researched far and wide. Summary below.

Use-case and tech-stack: Using Passport.js to implement Google OAuth authentication with React and Express. Using CORS in express. Also, set-up a middleware in Express to add Access-Control-Allow-Origin, Access-Control-Allow-Headers and Access-Control-Allow-Credentials to each response. Still did not work.

Solution: Only solution that seems to work is to use an href from the front-end to call the authentication URL (e.g. /auth/google). Or to set-up a proxy from the client to redirect requests to the server (Have not tried or tested this yet).

Long-term solution: Passport.js needs to add same-site=none to the cookie it sends to the client for chrome to allow redirecting the requests with fetch.

Core issues: axios doesn't work due to redirect issue. OAuth API need to redirect to client URL after authentication. Fetch doesn't work due to Chrome same-site=lax cookie issue. XHR faces issues as well. Perhaps a combination of redirect, cookies and CORS challenges.

P.S. Also learned that setting res.header('Access-Control-Allow-Origin', '*') in Express doesn't work for axios. axios seems to require a specific domain

Jay Sharma
  • 19
  • 3
  • 1
    PassportJS already supports changing the `sameSite` and `secure` fields for the cookies it sets; however, these settings are controlled by the specific session middleware that PassportJS employs, rather than configurable through PassportJS itself. See here for an example (with the [cookie-session](https://github.com/expressjs/cookie-session) package): https://stackoverflow.com/a/69207405/2441655 – Venryx Sep 16 '21 at 11:18