A couple days ago, my partner and I built the server side for our (previously created) client side of Chatterbox–a group messaging web app. The client sends specific requests to the server, which then sends back the requested chat messages. Something we spent a reasonable amount of time debugging was the “OPTIONS” requests that our client side kept sending…and our server was apparently ignoring. I knew “GET,” knew “POST,” but what was this incredibly annoying “OPTIONS” request that prevented my much desired requests from going through? Turns out, this was a result of our server making cross-domain ajax requests to our client. Our server was not located at the same domain as our client, and they thus had different origins, so to speak.
In this particular case, we could have fixed this problem by making sure the client and server were located on the same origin. However, we decided to tackle the ‘OPTIONS’ request, because that is something that will be necessary any time you want to make Ajax requests to domains other than your own. For example, let’s say you work at Github (if only, right??), and you want to allow certain other websites to allow their users to log-in to the site with their Github account. These sites would have widgets that communicate with Github. You now have two origins in play. But, for security purposes, the browser has introduced restrictions on how you may communicate with domains other than the one you are in (the one in your url bar).
I won’t go into the details of the possible security implications of not having these restrictions, but imagine a lot of malicious code getting injected in lots of places and basically just breaking the internet. A major drawback of these restrictions is that it makes it much more difficult for our website to communicate with other websites. Over the years, various techniques have been used as workarounds, one of which is called CORS – Cross Origin Resource Sharing.
In layman’s terms, CORS is like a handshake between your domain and the server you want to interact with. You reach your hand out, and the server agrees (or disagrees) to shake it. More specifically, when the browser notices you are making an Ajax request to a domain other than your own, it will suspend your Ajax request and call out to the server with an ‘OPTIONS’ method that provides information about the origin, and basically asks the server: “What is your allow policy?” The server should then ideally be set up to respond to ‘OPTIONS’ requests with a response that includes headers that indicate whether it will serve resources to the origin, as well as what specific actions your domain is allowed to perform on the server (i.e. get, post, etc.). If the server responds with a heading of “Access-control-allow-origin: *”, that means all origins are allowed, and hurray–your Ajax request can go through. The server can be even more specific, and may very well choose to respond and say that it will only allow certain methods (GET ok, but not DELETE), or it may respond that it will not serve any sort of resources to the origin. (Check out how the Github API supports CORS here!) This exchange, much like a handshake, is what makes CORS secure.
CORS is supported by all major browsers. So now are you considering your options? Of CORS you are!