2

I'm writing an API that will interface with an SPA front-end. For simplicity I currently have the API at api.example.com, and the SPA itself is at example.com. I have CORS set up and everything is working correctly.

In my ignorance, however, I was unaware that a preflight request is sent for quite a few method calls. I've since researched CORS more and understand more of the implications.

My question is this: Is it better for performance or any other reason to host both the API and the SPA on the same origin?

  • 1
    Have you tried measuring with and without CORS to see how much of a time difference there is? Hard data like that will help you make a better decision. – Robert Harvey Nov 14 '16 at 22:25
  • You might run into a problem supporting older versions of IE, but then again, your SPA probably won't support them either. – Sam Dufel Nov 14 '16 at 23:48
  • 1
    hosting client and server on the same host and port has far more to do with granularity of the design, security, reusability, and ease of maintenance than a potential slight performance increase. – jwenting Nov 15 '16 at 7:06
  • We are at testing an API hosted on server 1 and database on server 2. By using internal IPs to fetch data, we can close server 2 from outside traffic. Which is safer. As the internal network is 1 Gbit, it makes literally no effect on the speed. – sibert Apr 29 '18 at 8:39
  • Speculating without measuring is a hallmark of junior-mid devs. Do you have any idea of the actual scale? – Josh Oct 27 '18 at 7:50
1

Q: My question is this: Is it better for performance or any other reason to host both the API and the SPA on the same origin?

It's not a matter of performance. Security and performance rarely get along. I would dare to say it's a matter of convenience. Organising applications under the same "umbrella" (domain) ease the handling of CORS, cookies and session reuses (SSOs). From the company standpoint, it looks more corporative too. On the other hand, it's cheaper having a single certificate (for the TLS) than one for each domain. Not to mention the burden of having to track the expiration of each certificate and its renewal. Take StackExchange as an example, +100 different subdomains under the same origin *.stackexchange.com.

Deploying both applications under the same origin doesn't require us to deploy and run both on the same host or network. They can be deployed and run in different environments and still work under the same origin (this is fairly common on the cloud). So, working under a common origin (domain) doesn't guarantee better performance. It could if both applications were deployed and run one next to the other or at least within the same infrastructure.

Q: Should I avoid using CORS if possible?

As any security solution, it should be studied and adopted according to real threats and vulnerabilities. Since CORS is configurable, I would not remove it totally. Even if our SPA is the only client, the API is still public and it could be interesting for you to have a security resource to limit the access to the API.

If you make it configurable, you can adopt different configurations for development, testing and production without too much overhead. In the worse case, disabling CORS would take a special configuration such as Access-Control-Allow-Origin: *.

Additionally, CORS can be handled at the Web (HTTP) tier instead of at the application tier. Handling CORS at the web tier extends the security to other areas (other APIs, sites, blogs, etc) within the same domain. In other words, a single point of failure but also a single point of configuration.

  • Security and performance barely get along (maybe should have said rarely instead of barely, but either way: take that statement to the bank!) – jleach Apr 24 at 10:50
  • Rarely sounds good too. I leak quite a bit on English vocabulary. Edited – Laiv Apr 24 at 10:51
0

If you backend ONLY receives requests from your client then sure you can have both client and server on same origin and that will simplify your deployment as no need to setup CORS on the web server.
CORS is needed for securty reasons so don't worry aobut performance, it needs to be enabled to allow your backend to process requests form other origins as you already know.

0

It's possible to prevent preflight errors from specific IP addresses and Ports which is the recommended way to host multiple interfacing services, with a conditional first set up to handle pre-flight requests.

With relation to your question, it would depend on what the objectives are within your application. Given that both services are hosted on the same IP through different ports you will still receive CORS issues as the IP and the port have to match.

Hosting both services on the same machine would likely reduce latency, that hosting them on the same port and the same IP.. would be defeating of an client/server architecture, and if the API server is listening on a port.. it may block the SPA's access to operate.

The short answer is that people won't realise much different within their user experience until the system scales, however it may be unfeasible to have the API server on say port 4200 with the client access also on 4200, you will likely be required to use another port (ie 80) for the SPA, meaning separate ports so there would still be CORS. I would say the best option would be to disable CORS errors from all computers when prototyping and then narrow it down to the SPA IP.

As a small additional note you need to be explicit with the IP, as using "localhost" as the SPA IP will refer your your computer's localhost and not the server's localhost that hosts the API server.

-1

For localhost development, having both on the same server is much simpler due to the fact that the origin is the same. Also, for headless browser testing, this simplifies the configuration necessary to test successfully. The same goes for testing mobile apps which use web views. The overhead is less in general as well, but the lack of parity across environments will require some architectural work:

Every Heroku app runs in at least two environments: on the Heroku platform (we’ll call that production) and on your local machine (development). If more than one person is working on the app, then you’ve got multiple development environments - one per machine, usually. Usually, each developer will also have a test environment for running tests.

This separation keeps changes from breaking things. You write code and check the site in development, but you run your tests in the test environment to keep them from overwriting your development database. Similarly, you might have broken features in your development environment most of the time, but you only deploy working code to production.

Unfortunately, this approach breaks down as the environments become less similar. Windows and Macs, for instance, both provide different environments than the Linux stack on Heroku, so you can’t always be sure that code that works in your local development environment will work the same way when you deploy it to production.

The solution is to have a staging environment that is as similar to production as is possible. This can be achieved by creating a second Heroku application that hosts your staging application. With staging, you can check your code in a production-like setting before having it affect your actual users. As you already deploy with git, setting up and managing these multiple remote environments is easy.

References

  • 3
    How does this answer OP's question about performance? – 1201ProgramAlarm Jun 28 '18 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.