Cannot get correct CORS headers on Preflight request

Hi guys

I’ve searched around a bit for answers to this but seem to be hitting brick walls wherever I go. I have the following serverless.yml file:

functions:
  createVote:
    handler: api/index.createVote
    events:
      - http:
        path: votes/{id}
        method: post
        cors:
          allowCredentials: true
          origins: 'http://localhost:3000,https://mydomain.com'
        request:
          parameters:
            paths:
              id: true

And a function which I am using middy to implement cors:

export const createVote = middy(() => {...})
    .use(cors({ origins: ['http://localhost:3000', 'https://mydomain.com'] }) )

But if I make this request on localhost:5000 then two things happen. Firstly the preflight request passes, where I would have expected this to throw a CORS error. The access-control-allow-origins response header is empty, but I would have expected it to contain on of the domains above.

Secondly the POST request succeeds, but the response is not visible due to the CORS error. I believe this is the expected behaviour.

So my question is how can I properly set allowed origins for a request as it seems like if the preflight check passes then the real request gets run, which seems to defeat the purpose?

Thanks!

For anyone else who runs into this issue, I managed to figure out what the issue was.

I was doing all my testing on localhost and trying different ports e.g. localhost:3000 vs localhost:5000

There are two things you may run into while doing this:

  • If you are running this locally, the serverless-offline plugin will change the access-control-allow-origin header to always match the incoming origin.
  • If you have deployed to AWS it will let any localhost port through ( or maybe it ignores the port all together, not sure ). I’m not sure if you need to have localhost in the allowed origins for this to work or not. I had ‘http://localhost:3000’ and was testing from ‘http://localhost:5000’. AWS was accepting any localhost port for some reason. But if you test from an external site it actually works as expected.

Silly issue, but not well documented, so hope someone else finds this useful.