expressjs / cors

Node.js CORS middleware
MIT License
6.07k stars 469 forks source link

Multiple cors middlewares on same request? #79

Open olalonde opened 8 years ago

olalonde commented 8 years ago

I have an API where I want every path to be CORS-enabled for all origins except for /auth/connect/twitter because it uses a cookie based session.

I was wondering if it would be possible to make it so that the last cors() middleware always overrides precedent ones. E.g.

router.use(cors())
router.use(cors({ origin: 'http://mydomain.com' }))

should set the Access-Control-Allow-Origin to http://mydomain.com. Is that possible?

sjberry commented 8 years ago

Running into the same issue. From what we can tell multiple calls to cors strictly append to the existing headers. While there may be a use case for this, not being able to override this behavior is a non-starter.

We don't want Access-Control-Allow-Origin to be *,http://example.com.

Probably just going to gut cors for now since this is time sensitive.

EDIT: You can specify preflightContinue to add specific header overrides using express' native .setHeader() on OPTIONS requests. This resolves our problem, but @olalonde's use case is still not possible so far as I can tell (it's obvious in the source code as to why this is the case and it's probably working as intended).

olalonde commented 8 years ago

Yes, I ended up doing something like this:

    const corsMiddleware = cors()
    router.use((req, res, next) => {
      if (req.path.match(/^\/auth\/connect\//)) {
        // let later cors middleware handle it!
        return next()
      }
      return corsMiddleware(req, res, next)
    })
troygoode commented 8 years ago

I like your solution @olalonde

ghost commented 6 years ago

I was looking into the code for cors today and I think it might be supported out of the box. It appears that there are undocumented code that supports regular expressions and arrays. When you pass an object to cors() it calls the private function isOriginAllowed with what is inside the origin property if that is not a function. That supports Array and RegExp, so you could actually have a regular expression for your domain. And it will only add the Access-Control-Allow-Origin Header if req.headers.origin matches

function isOriginAllowed(origin, allowedOrigin) {
    if (Array.isArray(allowedOrigin)) {
      for (var i = 0; i < allowedOrigin.length; ++i) {
        if (isOriginAllowed(origin, allowedOrigin[i])) {
          return true;
        }
      }
      return false;
    } else if (isString(allowedOrigin)) {
      return origin === allowedOrigin;
    } else if (allowedOrigin instanceof RegExp) {
      return allowedOrigin.test(origin);
    } else {
      return !!allowedOrigin;
    }
  }
aman-ka commented 3 years ago

hey Hii every one i am new to opensource world can any one help me in making my first contribution in this library.by explaining it more to me and guiding me.