serverless-cors-plugin icon indicating copy to clipboard operation
serverless-cors-plugin copied to clipboard

Add option to dynamically set Access-Control-Allow-Origin header

Open joostfarla opened this issue 10 years ago • 6 comments

As discussed with @chadkouse in https://github.com/joostfarla/serverless-cors-plugin/issues/1.

When providing authenticated requests with the withCredentials option, CORS requires you to set a specific host in the Access-Control-Allow-Origin header. CORS doen not allow a wildcard (*) origin for authenticated requests.

We could implement an option which dynamically sets the Access-Control-Allow-Origin header equal to the request's Origin. This would enable to allow authenticated cross-origin requests coming from anywhere.

joostfarla avatar Jan 01 '16 12:01 joostfarla

Yeah! This option would be extremely useful due to the particular requirements that browsers enforce for CORS requests. Especially over HTTPS.

Here's one way that you can enable CORS with dynamic origin in an Express app. Since the 'cors' package is pretty popular on npm, IMO it would be convenient to have a similar interface:

// Enable CORS in an express app for all methods (including OPTIONS).
// The `{ origin: true }` config attribute makes the server respond with an 
// 'Access-Control-Allow-Origin' value equal to the request's host.
// See: https://github.com/expressjs/cors#configuring-cors-w-dynamic-origin
var cors = require('cors')
var app = express()
app.use(cors({ origin: true, credentials: true }))
app.options(cors({ origin: true, credentials: true }))

theopak avatar Jan 20 '16 17:01 theopak

I'll have a look at the Express syntax, thanx!

joostfarla avatar Jan 21 '16 10:01 joostfarla

Would love to see your solution to this. I just recently talked to AWS support about doing this and the workaround solution they gave me as the only way to currently achieve this was to have the OPTIONS gateway contain an integration map that stores the headers on an object, calls a lambda that simply returns the event with the headers and then map the origin response header to the value of the origin header passed through the lambda. Would be willing to share the config if it helps, or if there's a better way to achieve this without an additional lambda that was overlooked.

DigTheDoug avatar Mar 05 '16 14:03 DigTheDoug

@DigTheDoug that is unfortunately the only way to achieve this. I'll try to implement this into this later this week!

joostfarla avatar Mar 08 '16 06:03 joostfarla

Just had a quick look at this issue. This seems to require more than just adding support to the plugin.

Each Lambda needs to:

  • Retrieve the Origin from the client using the request mapping
  • Pass it back to the success callback
  • Map it to the response header in the endpoint integration mapping config
  • Have a non-mock preflight endpoint which behaves identically

It has some overlap with another idea I'm working on. Let's see if we can make this work.

joostfarla avatar Mar 11 '16 12:03 joostfarla

Ideally, we would be able to use method.request.header.Origin in the response mapping, but currently you do not have access to method.request.* parameters on the response.

brettstack avatar Mar 27 '16 02:03 brettstack