Working With Cross-Origin Resource Sharing
Client code will need to access resources from S3 and API Gateway, which will be on different domains. To prevent online fraud, browsers request special authorisation when a page from one domain wants to access resources on another domain. This is cross-origin resource sharing (CORS). Here’s a quick introduction to how CORS works. It should be enough for your needs in this course (for a more in-depth introduction to CORS, check out the Cross-Origin Resource Sharing documentation page on the Mozilla Developer Network):
The resource server is supposed to reply to the pre-flight request repeating the requested origin and providing a list of HTTP headers and methods it would allow for that resource. Technically, the server response needs to include the policy in the
Access-Control-Allow-Headers HTTP headers.
CORS security errors are particularly tricky to troubleshoot because they only apply to background browser actions. Running exactly the same request from a command line, for example using
curl, won’t show any problems. You also won’t find any logs on the server about such problems, because browsers kill requests before they even reach your API.
The first step in the figure, retrieving the web page, is a direct request, so it falls outside CORS.
The third step (‘upload file’) will post a form dynamically to the uploads bucket URL, also on a different origin and restricted by CORS.
The fourth step (‘get results’) also requires CORS, because you’ll be polling the results bucket dynamically to check whether the file is ready.
The second and third CORS issues are easy to address. Because S3 supports basic web serving features, including CORS, you can use CloudFormation to configure CORS policies on S3 buckets. You just need to add the CORS origin (the website endpoint for the static assets) to the upload and thumbnails bucket using the
The upload bucket should only allow
POST requests across origins, and only from the pages loaded from the assets bucket. The
UploadS3Bucket resource is changed in your template to match the following listing (the important changes are in lines 8-16).