Be Careful Running Multiple Localhost Apps
How to run a localhost app using 127.0.0.1 and the issues you can have if you don’t
Testing apps locally by accessing them over localhost is perfectly fine majority of the time.
But what happens when you need to manipulate cookies from the backend?
The Issue
Recently I ran into an issue where logout functionality wasn’t working.
I had a .NET client app which was using Duende Identity Server as the identity provider. The apps were running using localhost:44300
for the client, and localhost:44349
for Identity Server.
My logout method in my client code was calling _httpContext.RemoveAllCookies()
which would expire all the cookies in the response.
The problem was, it was expiring the cookies issued by the client (localhost:44300
) and Identity Server (localhost:44349
), instead of just localhost:44300
.
This meant the Identity Server cookie was being expired too early, which resulted in the logout functionality in Identity Server not working.
Cookies do not provide isolation by port
According to RFC 6265:
Cookies do not provide isolation by port. If a cookie is readable by a service running on one port, the cookie is also readable by a service running on another port of the same server.
This means it doesn’t matter if the ports are different, your browser will send cookies for localhost, to any localhost application, regardless of the port number.
The Solution
I made requests to the client using127.0.0.1:44300
, while requests to Identity Server still used localhost:44349
.
How to replace localhost with 127.0.0.1
If you want to be able to make requests using the home address (127.0.0.1
) instead of localhost, you need to do the following:
Run cmd as admin and run these commands (update portNumber
with your actual port number):
netsh http add urlacl url="https://*:portnumber/" user=everyone
netsh http add urlacl url="https://localhost:portnumber/" user=everyone
If you’re using Visual Studio, edit \.vs\config\applicationhost.config
to have this in your app's bindings section:
<binding protocol="https" bindingInformation="*:portNumber:localhost" />
<binding protocol="https" bindingInformation="*:portNumber:*" />
Make sure it’s listed in that order.
Run VS as admin, and you should be able to go to https://127.0.0.1:portnumber
.