DEV Community

Cover image for TIL: CORS, IPs, and the Day My Demo Crashed 🔒
Mai Chi Bao
Mai Chi Bao

Posted on

TIL: CORS, IPs, and the Day My Demo Crashed 🔒

Everything worked perfectly on my laptop. 🚀 The UI loaded, uploads succeeded, APIs responded instantly.

But on demo day, in front of my boss, everything collapsed. 💥

This post is a breakdown of how VS Code Remote-SSH port forwarding tricked me, how I fixed it, and what I learned.

If you’ve ever wondered why your app works fine locally but fails when someone else tries — this story might save you some embarrassment.


Key Takeaways 📝

  • Why localhost tricks you in Remote-SSH and how VS Code port forwarding can hide real network issues.
  • How to correctly configure backend (0.0.0.0), frontend (server IP/hostname), and CORS so others can access your app.
  • Why testing in a clean environment (without port forwarding) is essential before demo day.

Table of Contents


The Setup and Demo Day Disaster ⚡

In my frontend .env I had:

REACT_APP_API_BASE=http://localhost:6489
Enter fullscreen mode Exit fullscreen mode

And in backend:

BACKEND_PORT=6489
BACKEND_HOST=localhost
Enter fullscreen mode Exit fullscreen mode

On my laptop (via VS Code Remote-SSH) everything worked. UI loaded, uploads went through, API calls succeeded.

But demo day came. My boss opened:

http://10.X.X.X:6485
Enter fullscreen mode Exit fullscreen mode

The frontend loaded, but every upload and API call failed.
I was lost — why does it only work on my machine, but not his?


Chasing the Problem 🔍

At first, I thought the backend had crashed. Logs were fine.
Then I suspected CORS. No issues there either.

Finally, I asked ChatGPT. It suggested:

Change backend host to 0.0.0.0 and frontend API base to server IP.

I tried it — and it worked. 🎉
But I still didn’t understand why it only worked for me before.


VS Code Port Forwarding: The Hidden Culprit 🎭

Digging deeper, I discovered the real cause:
VS Code Remote-SSH was auto-forwarding my ports.

On my laptop:

  • localhost:6485 → tunneled to frontend on the server
  • localhost:6489 → tunneled to backend

So for me, everything looked fine. But for my boss, localhost pointed to his own machine — which had no backend at all.

Visual proof of the trick:

Before (VS Code auto port forwarding): You now can access via localhost:6485 and 10.X.X.X:6485

Deleting ports → no more fake localhost:

Now only server IP works:

⚠️ Note on VS Code Port Forwarding
If you run two VS Code Remote-SSH sessions for different projects, and both try to use the same port, VS Code will automatically increment the port number.

That’s why sometimes when you open http://localhost:6485, it gets auto-routed to http://localhost:6486.


Why Auto Port Forwarding Matters 🔑

When I added authentication, using the server IP broke Microsoft login — it only accepts localhost or HTTPS.

Error when opening via server IP (10.X.X.X:6485) without port forwarding:

Fix: forward ports in VS Code (or manually with SSH):

ssh -L 6485:localhost:6485 -L 6489:localhost:6489 user@10.X.X.X
Enter fullscreen mode Exit fullscreen mode

Now login works again on http://localhost:6485:

⚠️ But there’s a catch:
This solution is fine for local development, but not practical for demos — you can’t expect customers to forward ports.

If your app relies on Microsoft login (or similar auth), you should set up HTTPS on the server.
That way, customers can simply access it via:

https://10.X.X.X:6485
Enter fullscreen mode Exit fullscreen mode

But after that, new CORS problems surfaced — which leads to the next lesson.


The Fix 🛠️

I fixed configs:

BACKEND_PORT=6489
BACKEND_HOST=0.0.0.0
Enter fullscreen mode Exit fullscreen mode

Frontend:

REACT_APP_API_BASE=http://10.X.X.X:6489
Enter fullscreen mode Exit fullscreen mode

Why this works:

  • localhost (127.0.0.1)
    Binding your backend to localhost means it only accepts connections from the same machine it’s running on.
    In other words, the server is listening only to itself. Anyone trying to reach it from another device on the network won’t be able to connect.

  • 0.0.0.0
    Binding to 0.0.0.0 tells the backend to listen on all available network interfaces (LAN, Wi-Fi, etc.).
    This makes your service accessible not just from the local machine, but also from other devices on the same network — such as your boss’s laptop during the demo.

  • Frontend API calls
    Since the frontend runs in your user’s browser, it can’t resolve your localhost (that points to their machine, not your server).
    The frontend must call the backend using the server’s IP address or hostname (e.g., http://10.X.X.X:6489), so that it correctly points to the server where the backend is actually running.


The CORS Twist 🔄

Later, I caught another mistake.
My backend allowed only SERVER_IP, but when the frontend ran on a different machine (FRONT_END_IP), the requests were blocked.

Fix was to add both:

if FRONT_END_IP:
    allowed_origins.append(f"http://{FRONT_END_IP}/")
    allowed_origins.append(f"https://{FRONT_END_IP}/")
Enter fullscreen mode Exit fullscreen mode

I had lazily assumed SERVER_IP == FRONT_END_IP. Wrong — and it silently broke requests.


Conclusion ✅

  • localhost ≠ server IP.
  • Remote-SSH port forwarding can trick you.
  • Always bind backend to 0.0.0.0.
  • Always point frontend to server IP or hostname.
  • Align CORS with the actual machine hosting frontend.
  • Test from a clean environment, not your tunneled setup.
  • And before demo day → disable VS Code auto port-forwarding.

👉 Future me: no more blind trust in localhost.

Top comments (2)

Collapse
 
mrzaizai2k profile image
Mai Chi Bao

⚠️ CORS + port forwarding… the perfect recipe for chaos. Thanks for sharing the fix!

Collapse
 
shaq_attack profile image
Shaquille Niekerk

The age old dilemma of "It works just fine on my PC"... How long did it take to get the Demo back up and running?
I can't imagine the panic that pursued trying to fix it ASAP