Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional credentials? #336

Closed
alxndrsn opened this issue Nov 13, 2024 · 2 comments · May be fixed by #337
Closed

Conditional credentials? #336

alxndrsn opened this issue Nov 13, 2024 · 2 comments · May be fixed by #337
Labels

Comments

@alxndrsn
Copy link

Would there be support for configuring the Access-Control-Allow-Credentials header dynamically? It looks like currently the only valid values for the credentials config option is true. Allowing a function similar to the origin option would allow for setting Access-Control-Allow-Credentials based on the request.

alxndrsn pushed a commit to alxndrsn/express-cors that referenced this issue Nov 19, 2024
@jonchurch
Copy link
Member

jonchurch commented Nov 27, 2024

Do you have example code you can share for what you're trying to do in your app?

You can configure CORS options on a per request basis by passing in a function when setting the middleware up. https://github.com/expressjs/cors#configuring-cors-asynchronously

Each request that comes in can get a chance to determine the CORS options which should be used.

I can see the need for a function for credentials if you don't have the information you need until further down in the handler logic.

It would be simpler for sure. But want to understand the usecase here before making every option either a value or a function. credentials is a good candidate for being a function, but still want to better understand your usecase.

@alxndrsn
Copy link
Author

alxndrsn commented Nov 28, 2024

Do you have example code you can share for what you're trying to do in your app?

I was doing something like:

cors({
  origin: ['a', 'b'],
  credentials: true,
});

It seemed inconsistent to send Access-Control-Allow-Credentials but not Access-Control-Allow-Origin when the Origin was not found in the configured array.

You can configure CORS options on a per request basis by passing in a function when setting the middleware up. https://github.com/expressjs/cors#configuring-cors-asynchronously

Thanks, this seems adequate. I've ended up with something like:

app.use(() => {
  const wrapped = cors((req, callback) => {
     try {
       const { allow, credentials } = getOptions(req);
       if(allow) {
         callback(null, {
           origin: true,
           credentials,
           methods: 'GET,POST', // keep it simple
           maxAge: 86400, // max(firefox, chrome) - see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
         });
       } else {
         callback(null, { origin:false }); 
       }
     } catch(err) {
       callback(err);
     }   
  }); 
  return (req, res, next) => {
    wrapped(req, res, () => {
      res.vary(varyHeaderFor(req));
      next();
    }); 
  };  
});

function varyHeaderFor({ method }) {
  switch(method) {
    case 'OPTIONS': return 'Origin, Access-Control-Request-Headers';
    default:        return 'Origin';
  }
}

where getOptions(req) is app-specific code.

The Vary header also seemed to need additional manual handling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants