http://localhost:3000 can’t call your remote API because of browser-enforced limitations involving CORS, cookie sharing, and HTTPS.
local.yourdomain.com on your dev machine so your browser will successfully call your remote service at
api.yourdomain.com, for example.
Add a custom host to your
/etc/hosts file (location of hosts file varies by OS):
127.0.0.1 localhost 127.0.0.1 local.yourdomain.com
The domain you set here depends on the domain of the API. If, for example, the API server you’re trying to call is
staging.api.yourdomain.com and that server’s CORS settings are configured to allow
local.yourdomain.com then you would add
local.yourdomain.com to the hosts file. If the server’s CORS config allows
*.yourdomain.com then you could technically use any subdomain you want. The point is whatever your server CORS settings allow your local host needs to be a match.
domain should be set to this host (or at least set to the domain, e.g.
.yourdomain.com) so the browser will pass cookies to the remote API.
This will vary by OS, but
brew install nginx is recommended on macOS.
Again, brew makes this easy. Run these two commands:
brew tap guardian/homebrew-devtools brew install guardian/devtools/dev-nginx
Then in your app’s root directory create a file named
nginx-mappings.yml and paste this in it:
name: your-domain domain-root: yourdomain.com mappings: - port: 3000 (or whatever your local app server is running on) prefix: local
cd to your app’s root if you’re not already there and then run:
dev-nginx setup-app nginx-mappings.yml
This creates an nginx config based on that YAML file, sets up a certificate for local HTTPS, and restarts nginx. You may need to restart you app server, but then you should be able to access https://local.yourdomain.com!
If you can access your new
local.yourdomain.com but the browser is still failing to call the remote API, there are a number of things to double-check. These include:
- Any required cookies have a matching
- The API server CORS settings using a wildcard (
*) to allow any domain. This setting prevents browsers from sending auth tokens (i.e.
Authorizationheader and cookies can't be sent).
I wanted to do this with as simple a setup as possible, but couldn't find anything explaining how to do this directly with an Apache server or nginx without the dev-nginx tool (not that the tool isn't good - it was a lifesaver!).
If you know how to achieve this without extra tools, please share in the comments and I'll update the article for others.