I had a question a few days ago, and am going to bring it up at this month’s Austin API meetup: should you use CORS in an API? I suppose that that leads into another question: should your API be built to be used by an application running from someone’s browser that is served on a domain other than your own?
For the less-informed, CORS allows an HTTP request from within a web page (namely a JavaScript XHR) to hit a domain other than what’s dictated by Same Origin Policy, a security measure that browsers implement to keep the web from degenerating into one big XSS attack. Yes, I expect you to read through the linked items on this one.
First, one big reason why you wouldn’t want this: your API is (semi) internal, or you only want it to be accessed in a “business to business” fashion, by someone else’s (or your) server-side systems. When you’re dealing with server-side scripts like PHP, there really isn’t the strong concept of Same Origin Policy like you find in JavaScript. In this case, if a third party wanted to use your API in an app that sat on someone’s browser, they would pull from your API server-side, mangle the data as needed, then push it out from their own domain to their users.
But what if you want to do a cool client-side mashup, utilizing the ever-increasing power of client-side code (JavaScript in this case…I’m just talking about web apps here) to interact with a variety of web services and do the result-wrangling in the user’s browser (remember, many APIs return JSON today, and JavaScript works great with JSON)? Well, you can’t do that, because Same Origin Policy prevents you…
…except there’s something called JSONP that has been around for ages and serves as a workaround for exactly that issue. If the API provider wants to provide its API cross-domain, even browser-side, they can wrap their JSON data structure in a callback and the browser will pull it right down. It’s a bit of an uncomfortable situation, since now you’re executing code where you really only needed (non-executable) data. But it worked, and it allowed you to mash up data from various sources without a bunch of server-side processing.
As time went on, forward-thinkers in the web world realized that injecting code when you could be injecting data is a security risk that we really should live without. Hence, CORS. A sufficiently advanced web browser (What. The. Expletive Deleted. IE.) tells a not-same-domain server “I want this data, and I’m coming from this not-you domain.” The server sees this header, decides whether to send the data based on, among other things, the source domain header, and responds back with either an error or the data, plus a header that lists allowed domains (or the wildcard * for everything) for cross-origin requests.
So that brings us back to the question of whether a web browser should be allowed to, if correctly authenticated, call your API directly, or whether you will only allow any non-web-browser client to make a request…but not web browsers, due to some perfectly valid reason(s) that will undoubtedly get discussed at the API meetup. You can probably tell which side of the fence I’m on, though I concede that building CORS into your API is a bit of extra work, and there are certain APIs that you really only want to be server-to-server.
But what do you think? Comment, or show up at the meetup if you’re in the Austin area and voice your opinion there.