Check out this blog post to catch up on all things CORS.
CORS is in place to prevent you from a sneaky bait and switch. It also allows you to get around the errors produced by legitimate interactions between known origins. But there are ways to get around this, and we’ll dive in below!
Types of CORS requests
Now that’s the short and short of it. Let’s dig a little deeper. There are two types of CORS requests: simple and preflighted. A simple request can be initiated directly. Simple. A preflighted request must send a preliminary, “preflight” request to the server to get permission before the primary request can proceed. That is, the client has to ask and server has to give the “green light” before the data can be served.
There are several circumstances under which request is preflighted
- it uses methods other than GET, HEAD or POST
- it uses the POST method with a Content-Type other than these types
- it sets custom headers.
For example, if your app uses PUT to ensure idempotent requests, this request would need to be preflighted.
The CORS request process
Let’s look at what happens when a browser makes a simple request to Cloud Storage.
- The browser adds the `Origin` header to the request. The `Origin` header contains, as you might have guessed, the origin of the resource seeking to share the other domain’s resources.
- Cloud Storage compares the HTTP method of the request — like GET or POST — and the value of the `Origin` header to the “Methods and Origins” information in the target bucket’s CORS configuration to see if there are matches.
- If there are, Cloud Storage includes the `Access-Control-Allow-Origin` header in its response. The `Access-Control-Allow-Origin` header contains the value of the Origin header from the initial request.
- The browser receives the response and checks to see if the `Access-Control-Allow-Origin` value matches the domain specified in the original request. If they do match, the request succeeds. If they don’t match, or if the `Access-Control-Allow-Origin` header is not present in the response, the request fails.
A preflighted request performs some additional steps first before following the same steps as a simple request.
- The browser sends an `OPTIONS` request containing the Requested Method and Requested Headers of the primary request.
- The server responds back with the values of the HTTP methods and headers allowed by the targeted resource.
- If any of the method or header values in the preflight request aren’t in the set of methods and headers allowed by the targeted resource, the request fails, and the primary request isn’t sent. If the method or header values are included, the request continues like a simple CORS request.
Now this is a very simplified description of CORS. If you’re loving this topic and eager for a complete description, read the Cross Origin Resource Sharing spec.
Configuring CORS for Google Cloud Storage
Hopefully things haven’t been too spooky so far, but I totally get if you need to turn the lights on and take a break. Once you’re ready to come out from under your blankets, let’s talk about how you configure CORS for Cloud Storage.
Cloud Storage allows you to set CORS configuration at the bucket level only. You can set the CORS configuration for a bucket using the gsutil command-line tool, the XML API, or the JSON API.
Here’s an example of setting the CORS configuration with gsutil:
First, I need a CORS JSON document.
This JSON document explicitly allows cross-origin GET requests from origin1.example.com and may include the Content-Type response header.
Then I set the CORS configuration of the bucket to the JSON document.
gsutil cors set cors-json-file url
To remove the CORS configuration of a bucket, the gsutil command is the same. The difference is that the CORS JSON document is empty.
We’ve conquered CORS and configured our GCS buckets, effectively slaying the CORS error beast. It may return, but that’s a worry for another day.
Thanks for joining us for this quick Byte of Google Cloud Storage!