Developing software in the Real World

CORS and OpenWhisk web actions

By default, OpenWhisk will handle the relevant responses for CORS.

Specifically, it will respond to an OPTIONS request with these headers:

If you need to change what is sent or you don’t want to send these headers at all, then you need to do set the annotation web-custom-options to true and handle the OPTIONS header yourself.

Note that if you don’t set this annotation, you must not set any of these headers yourself as you’ll break things!

Implementing the CORS headers yourself

To implement the CORS headers yourself you do something like this in your action (example in Swift, PHP version at the end):

Create it it OpenWhisk with:

For a “non-simple” request, the browser will send an OPTIONS request to the option that you need to respond to. This is call the “preflight” request.

The __ow_method in args will tell you the method (lowercased) and __ow_headers will contain all the headers that were sent.

If the method is options, then we need to return the CORS headers. You can expect that the client will send a Access-Control-Request-Headers header containing the list of headers that its going to send to you when it does the actual request. If you don’t have a white list of headers that you’re expecting, then you should send back the list you are sent as otherwise the request will fail.

You also need to set the Access-Control-Allow-Methods header to the list the methods you accept for this end point; it is the CORS version of the Allow header. The client should send you a Access-Control-Request-Method header to tell you the method it will use when it sends the actual request.

If the method is not OPTIONS, then you send back your response as usual. In addition, you need to send the Access-Control-Allow-Origin header with the same value as you used for the preflight request.

That’s it.

Aside: PHP version

As an aside, here’s how it looks in PHP, where the type handling is looser:

The PHP version operates in the same manner as the Swift one, so the discussion above applies to this code too. The most obvious differences are the lack of a guard section do handle the type & optional casting from the args dictionary and the ease of converting an array to a base64 string in PHP.

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *