symfony/mercure

This attempt to set a cookie via the Set-Cookie header was blocked....

Matts opened this issue ยท 8 comments

Matts commented

I am running mercure from a different subdomain
mercure.product.ota.internal.company.cloud

the app is running from
app.product.ota.internal.company.cloud

Whenever I want to use a discover as shown in the guide I get the following error within Edge (Blink) 95.0

image

I seen #54 and updated to 0.6.0, so most recent version

mercureAuthorization=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzU4NzMxNjcuNTgzMTY3MSwibWVyY3VyZSI6eyJwdWJsaXNoIjpbXSwic3Vic2NyaWJlIjpbIi9wcm9kdWN0aW9uL3NjZW5hcmlvLzIiXX19.8rdaR3akCcobIpCb9aBE7DptsuMvC_hsrzvEEePW5A4; path=/.well-known/mercure; domain=mercure.product.ota.internal.company.cloud; secure; httponly; samesite=strict

Am I reading something wrong or is this a browser issue?

Matts commented

I solved this by using a bearer token for now, but still according to docs you should be able to use cookies with subdomain

Same here, setting the cookie with a subdomain doesn't work ... in Authorization.php, only the hub url is taken into account for the cookie creation, so it's pretty normal that it fails.

@Matts would you mind sharing your solution with the bearer token by any chance ?

We have tests covering subdomains (AuthorizationTest.php). Could you please add a failing test so we can try to debug?

Hi @dunglas and thanks for your response

I don't think a PR will explain correctly what we're seeing here, here is my understanding:

  • in AuthorizationTest's provideApplicableCookieDomains(), you have a test for subdomains, that's right:
yield ['mercure.example.com', 'https://mercure.example.com', 'https://app.example.com'];
  • in this test, you assert that the cookie domain is mercure.example.com even though the app's domain is app.example.com, and the test passes.

  • the problem is, if your app is at https://app.example.com and tries to set a cookie for mercure.example.com, it will fail because the browser will reject the cookie (it's not the same domain) with the message (more or less, depending on the browser) "This Set-Cookie was blocked because its Domain attribute was invalid with regards to the current host url."

  • hence, the real correct test should be:

yield ['.example.com', 'https://mercure.example.com', 'https://app.example.com'];

which fails at the moment.

In a nutshell, I think the Authorization class should:

  • set a cookie for the hub domain is both app and hub domains are the same
  • set a cookie for the "top-level" domain (i.e. .example.com) if the hub domain and the app domain are not the same but they share the same top-level
  • throw in any other case

Happy to discuss, I hope I'm not missing anything here
Best regards and thanks for your work on all these awesome projects !

Matts commented

@tchapi for my solution I did the following:

Added the url and grant to an element (it could be a stimulus controller just did not get that far yet)
image

And then have a helper mercure interface in javascript to interpret the data attributes
image

That uses a wrapper to build a generic version:
image

The hasGrants and getGrants methods are custom twig functions that store an array in memory while building the twig template, allowing me to do this in extensions of base:
image

After building the hierarchy, it will interpret all the grants that have been added, and create a token for it.

The actual implementation is then this:
image

So whenever we want to connect on a new location, we add the grant to the twig and then use the impl

Oh ok I see, thanks a lot @Matts ! I hope the cookie method can get sorted since it looks far easier (and it's doesn't need a polyfill for EventSource)

Best

I'm working on a fix for this ๐Ÿ‘ will send a PR in a few :)

Thank you so much @azjezz ! ๐Ÿ‘Œ๐Ÿผ