localhost != 127.0.0.1

And it definitely is not like home. I recently had to deal with something I never thought possible.

Most of us are doing some local dev work, as in you are running the stack you have on production locally. That way you can debug and develop everything from the safety of your own machine. Now in order to access that page, everyone always talks about localhost. They might also say localhost is the same as 127.0.0.1. Oh how wrong they are.

Nuance

It is true that localhost points to 127.0.0.1. What exactly is 127.0.0.1 ? It is considered a local loopback device. In essence a dummy device that does not talk to any other network devices. As far as I can tell you can have no network cards in your machine and still have this local loopback device.

Now we get to world of the browsers and the modern web, which includes things like CORS. It deals with the concept of Origin and if things are on the same origin all is well and secure. Otherwise a CORS request needs to be executed and the party you are trying to access needs to accept that you are allowed to do it.

That is why my advice is to run everything on the same domain and route with namespaced routes. As in everything on app.domain.com with /api going to the backend and the rest for example to the frontend.

Now back to local stack development. I had an application running a MakoJS frontend with a NodeJS backend serving that. It was configured that the app was living at http://127.0.0.1:9000. So I went to http://localhost:9000 since I almost always do that. Then one day it stopped working. Cookies were messed up. In the console debug log I saw a CORS denied for http://127.0.0.1:9000. So I went to http://127.0.0.1:9000 but as you can guess the cookie is set for localhost and therefor the session in the NodeJS backend is lost across requests.

The actual problem I wanted to solve on 127.0.0.1:9000 was that the csrf token did not work. That did not work since the secrets bag on req.session was constantly being lost since there was no information tying these requests together from me. So then I could turn on cookies for csrf and that seemed to fix 127.0.0.1 but not the localhost CORS situation.

I also did not want to introduce a new cookie. Mind you the reason why the csrf cookie works is it is being set to 127.0.0.1 and not localhost. Now back to configuration settings. Then I set the base URL setting to http://localhost:9000 and then everything worked.

Lessons learned

I learned that web dev is frustratingly hard, and it is a good thing developers all use different environments. You learn a lot more and you can make things more robust that way.

I also learned that the origin check is for protocol, port and host. In that regard it makes sense to say objectively 127.0.0.1 and localhost are not the same string. That is true. Even though in practice it will be. Most of the time anyway. I am sure there is someone out there that did a /etc/hosts thing where localhost actually points to his VM running on another box with Proxmox because of security reasons.