Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpClient does not track cookies #16239

Closed
masonwheeler opened this issue Apr 9, 2018 · 10 comments
Closed

HttpClient does not track cookies #16239

masonwheeler opened this issue Apr 9, 2018 · 10 comments
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@masonwheeler
Copy link

If I @inject the HttpClient and make a call to a server, it doesn't keep track of the cookies the server sends back. Normally, this is handled by a parameter passed to the HttpClient's constructor, but with everything done via DI magic, this isn't happening in Blazor.

It needs to happen, preferably by default. Is there any way to make it happen currently? If not, can this be fixed?

@masonwheeler
Copy link
Author

This just keeps getting better. I tried to use Reflection to hack a HttpClientHandler containing a CookieContainer into the HttpClient, and it blew up at runtime when I tried to create the CookieContainer:

Unhandled Exception:
System.DllNotFoundException: libc
at (wrapper managed-to-native) >System.Net.NetworkInformation.CommonUnixIPGlobalProperties.getdomainname(byte[],int)
at System.Net.NetworkInformation.CommonUnixIPGlobalProperties.get_DomainName () <0x19cf590 + 0x0001c> in <7743947c1dd14f89925941b3d37bc74c>:0
at System.Net.CookieContainer..ctor () <0x19c7d90 + 0x00056> in <7743947c1dd14f89925941b3d37bc74c>:0
at MyApp.login+d__10.MoveNext () <0x19c6ec8 + 0x00028> in <51c28745efe740f29e480fc111234aaf>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_1 (System.Object state) <0x19d0d70 + 0x00014> in <919466a451a44d05a7b4a01cf38c4b39>:0
at (wrapper delegate-invoke) .invoke_void_object(object)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x19d0c00 + 0x00022> in <919466a451a44d05a7b4a01cf38c4b39>:0
at (wrapper delegate-invoke) .invoke_void_object(object)
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x183ab08 + 0x000f0> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x183a820 + 0x00020> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x19d0b80 + 0x00046> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x18381c0 + 0x000f4> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x1837340 + 0x00000> in <919466a451a44d05a7b4a01cf38c4b39>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: libc
at (wrapper managed-to-native) System.Net.NetworkInformation.CommonUnixIPGlobalProperties.getdomainname(byte[],int)
at System.Net.NetworkInformation.CommonUnixIPGlobalProperties.get_DomainName () <0x19cf590 + 0x0001c> in <7743947c1dd14f89925941b3d37bc74c>:0
at System.Net.CookieContainer..ctor () <0x19c7d90 + 0x00056> in <7743947c1dd14f89925941b3d37bc74c>:0
at MyApp.login+d__10.MoveNext () <0x19c6ec8 + 0x00028> in <51c28745efe740f29e480fc111234aaf>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_1 (System.Object state) <0x19d0d70 + 0x00014> in <919466a451a44d05a7b4a01cf38c4b39>:0
at (wrapper delegate-invoke) .invoke_void_object(object)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x19d0c00 + 0x00022> in <919466a451a44d05a7b4a01cf38c4b39>:0
at (wrapper delegate-invoke) .invoke_void_object(object)
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x183ab08 + 0x000f0> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x183a820 + 0x00020> in <919466a451a44d05a7b4a01cf38c4b39>:0
ExitStatus: Program terminated with exit(255)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x19d0b80 + 0x00046> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x18381c0 + 0x000f4> in <919466a451a44d05a7b4a01cf38c4b39>:0
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x1837340 + 0x00000> in <919466a451a44d05a7b4a01cf38c4b39>:0

Something is very wrong if this is trying to load libc to call Unix APIs, in a browser running on Windows!

@aguacongas
Copy link
Contributor

Did you read the thread : aspnet/Blazor#357 ?

@Suchiman
Copy link
Contributor

Suchiman commented Apr 9, 2018

@masonwheeler the HttpClientHandler is built on Sockets which aren't available in the browser 😈
There's a custom BrowserHttpMessageHandler to replace it.

@masonwheeler
Copy link
Author

masonwheeler commented Apr 9, 2018

@Suchiman HttpClientHandler isn't the thing that's blowing up on me; CookieContainer is. And BrowserHttpMessageHandler doesn't handle cookies. (And I don't see a BrowserCookieContainer.)

@RyoukoKonpaku
Copy link
Contributor

RyoukoKonpaku commented Apr 9, 2018

@masonwheeler strangely enough when I query the System.Runtime.InteropServices.RuntimeInformation.OSDescription it returns Unix, it might be related?

@SteveSandersonMS
Copy link
Member

Thanks for reporting this. Although it was possible to do before (via the fetchOptions API), I agree it was too difficult, and the default behavior of not sending any cookies was unhelpful.

So this is now fixed via dotnet/blazor#518. The new default behavior is to include cookies in same-origin requests. If you want, you can also change the default like this: https://github.com/aspnet/Blazor/blob/dev/test/testapps/BasicTestApp/Program.cs#L18

Note that setting a cookie container on HttpClient is not likely to produce the behavior you want. Typically web developers expect the cookies to be stored at a browser level, not at a .NET object level. For example, when a user closes your app then reloads it later, you expect to still have the cookies set earlier. Therefore it's not useful to be dealing with cookie containers on HttpClient, except in the more specialised scenario where you do want per .NET-object cookies.

@masonwheeler
Copy link
Author

masonwheeler commented Apr 9, 2018

Yeah, that does sound more useful. Thanks for fixing this up!

@GoranHalvarsson
Copy link

GoranHalvarsson commented Mar 16, 2019

Thanks for reporting this. Although it was possible to do before (via the fetchOptions API), I agree it was too difficult, and the default behavior of not sending any cookies was unhelpful.

So this is now fixed via dotnet/blazor#518. The new default behavior is to include cookies in same-origin requests. If you want, you can also change the default like this: https://github.com/aspnet/Blazor/blob/dev/test/testapps/BasicTestApp/Program.cs#L18

Note that setting a cookie container on HttpClient is not likely to produce the behavior you want. Typically web developers expect the cookies to be stored at a browser level, not at a .NET object level. For example, when a user closes your app then reloads it later, you expect to still have the cookies set earlier. Therefore it's not useful to be dealing with cookie containers on HttpClient, except in the more specialised scenario where you do want per .NET-object cookies.

Unfortunately, the link is dead, could you or someone please show what you meant(in code) instead of the link...

@Suchiman
Copy link
Contributor

@GoranHalvarsson this code now lives here https://github.com/aspnet/AspNetCore/blob/3189146b4e5c1811f6599ba38b5c8a0077128f24/src/Components/test/testassets/BasicTestApp/Startup.cs#L23

@rathga
Copy link

rathga commented Oct 26, 2019

It would be lovely if this was documented somewhere in the Blazor docs? It's just taken me two days to track down what was happening with my app and find this solution.

Is not having a CORS web api that stores an authentication cookie fairly common in an SPA?

https://docs.microsoft.com/en-gb/aspnet/core/blazor/call-web-api?view=aspnetcore-3.0 gets 90% of the way there near the end but doesn't quite nail it...

Thanks

@mkArtakMSFT mkArtakMSFT transferred this issue from dotnet/blazor Oct 27, 2019
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Oct 27, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

8 participants