Web applications used to be written as monoliths, the server and client intermingled. ASP.NET, PHP were typical of the type. There was no firm API between the presentation layer and backend. They were updated together. Gradually abstractions came in like Model View Controller, but the monolith remained.
More recently people have started writing applications where the browser is a richer first class citizen. Platforms like Angular, React are typical of the type. As these became popular the older ‘Form/Submit’ model gave way to the Single Page Application. The browser gained the logic to make it richer, more reactive to the user, and, the backend shrunk to being a mere data gateway.
And then we had an epiphany: why make any dedicated backend at all? Instead, have each application, running in the Browser, directly access a set of RESTful API’s. Great. Now we can evolve microservices without worrying about presentation. We can evolve presentation without worrying about data. And life was good.
But, like all good things in life, risks became real and crooks became rich. Flaws were found. And, like all such things, standards emerged to codify and solidify best practices. And, for the direct-consuming-api-application, we invented Cross-Origin Resource Sharing (called CORS).
Once upon a time the same-origin policy was sufficient: where you came from was where you could talk. Now we need more.
Now, CORS is very complicated to get right. You can indicate if authentication is allowed (to prevent credentials from being leaked), you can indicate who can talk where. As a consequence there is fixed set of headers which are sent for CORS, and yours may not be in the list! A server must manually indicate if it wishes to allow authentication (or any header other than the standard set).
Unlike its cousin the Content-Security-Policy, CORS is very simplistic in hosts. You get 1 or all. So you can say “example.com” or “*”. This can be challenging if you want a small set of origins to use your API. And by challenging I mean “write some complex logic on your server out scope of this presentation”.
Do you need this? If you write an API you must implement CORS, you have no choice. Make it so!
If you want to see how to use the Vary: Origin header to allow two applications in the same browser to work against the same API backend, see this post.