Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add SameSite Attribute to Passport.js Session Cookie

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);
like image 444
sean_x Avatar asked Dec 07 '19 00:12

sean_x


People also ask

How do I add the SameSite attribute to all cookies?

Android System WebView To prepare, Android allows native apps to set cookies directly through the CookieManager API. You must declare first party cookies as SameSite=Lax or SameSite=Strict , as appropriate. You must declare third party cookies as SameSite=None; Secure .

Where do I specify the SameSite attribute?

SameSite attributes You can add SameSite cookie attributes in the set-cookie HTTP response header to restricts browser behavior.

How do I fix my SameSite attribute?

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.


1 Answers

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

like image 157
Jay Sharma Avatar answered Oct 19 '22 09:10

Jay Sharma