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
Esi cache broken ? (started session / private response) #26769
Comments
can you provide a reproducer please? |
@nicolas-grekas Sure, I created a symfony 3.4.6 project here : https://github.com/EmmanuelVella/symfony You can use docker to bootstrap it : Then go to http://localhost:8000/app.php Interesting parts are the controller and the template. It seems that the firewall causes the session to start, and the response is then marked as private. Does it means I need to exclude all my esi actions from the firewall ? With firewall : |
Correct me if i'm wrong but it seems the problem relies in the |
@stokjes Yes, before symfony 4 this code was in I understand why the response is not cached if the session is started (which is the case if you use the firewall) ; however I don't know how to disable the firewall on the esi actions, as they have not route (they are called like this : |
What if you use the firewall on the whole domain like: For you shouldn't the |
@stokjes I don't know if this behavior is intended or not :/ |
Fixed by #27467 (please report back if not.) |
@nicolas-grekas your PR certainly fixed a part of the problem, but I still have an issue. I have updated my repository to symfony 3.4 branch (see #26769 (comment)). Please let me give you all the steps to reproduce : Please note that the app is behind the default firewall. When going to Once the fragment cache is stale (30s+), when refreshing the page the fragment won't be cached anymore (because of the session cookie ?). What I understand here is that the firewall uses the session, so the fragment can't be cached (why is it working the first time, then ?). If that's the intented behavior, how can I exclude my esi controller from the firewall, if it has not route ? Thank you so much for your patience / help. |
Can you provide a simple reproducer, ie a repo we could clone to experience the issue? |
I did it in a previous comment ;) Let me repeat it here : https://github.com/EmmanuelVella/symfony You can use docker to bootstrap it : Then go to http://localhost:8000/app.php |
@nicolas-grekas FYI, still not working with latest sf 3.4 update ! |
I checked out your app to reproduce and indeed it cannot cache, because as you spotted, the firewall is used on fragments, which uses the session, which makes the response uncacheable. Would there be any downside to disabling the security on |
Thank you so much for taking time to test it. Yeah I already tried this solution, and it works, but it felt a bit hacky.. so I wanted to be sure that this behavior was normal. So currently there is no other way to disable security on a controller (with no route) called like this |
I don't know security well myself, I'd need someone else to answer this... |
Ok ;) Do you know someone who could help ? |
Let's ask on symfony/recipes#424 :) |
👍 |
@nicolas-grekas I continue this discussion here to not pollute your PR. I'm sorry but I still don't get how to disable the firewall on controller called like this (with no route) : Could you please be more explicit ? |
Exactly like done here: https://github.com/symfony/recipes/pull/424/files |
Ok, so I will do this. Thank you very much for your help ! 👍 |
…ate only when needed (nicolas-grekas) This PR was merged into the 4.4 branch. Discussion ---------- [Security] Make stateful firewalls turn responses private only when needed | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #26769 *et al.* | License | MIT | Doc PR | - Replaces #28089 By taking over session usage tracking and replacing it with token usage tracking, we can prevent responses that don't actually use the token from turning responses private without changing anything to the lifecycle of security listeners. This makes the behavior much more seamless, allowing to still log the user with the monolog processor, and display it in the profiler toolbar. This works by using two separate token storage services: - `security.token_storage` now tracks access to the token and increments the session usage tracker when needed. This is the service that is injected in userland. - `security.untracked_token_storage` is a raw token storage that just stores the token and is disconnected from the session. This service is injected in places where reading the session doesn't impact the generated output in any way (as e.g. in Monolog processors, etc.) Commits ------- 20df3a1 [Security] Make stateful firewalls turn responses private only when needed
…colas-grekas) This PR was merged into the 4.4 branch. Discussion ---------- [Security] add "anonymous: lazy" mode to firewalls | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fixes #26769 et al. | License | MIT | Doc PR | - Contains #33663 until it is merged. This PR allows defining a firewall as such: ```yaml security: firewalls: main: anonymous: lazy ``` This means that the corresponding area should not start the session / load the user unless the application actively gets access to it. On pages that don't fetch the user at all, this means the session is not started, which means the corresponding token neither is. Lazily, when the user is accessed, e.g. via a call to `is_granted()`, the user is loaded, starting the session if needed. See #27817 for previous explanations on the topic also. Note that thanks to the logic in #33633, this PR doesn't have the drawback spotted in #27817: here, the profiler works as expected. Recipe update pending at symfony/recipes#649 Commits ------- 5cd1d7b [Security] add "anonymous: lazy" mode to firewalls
Hello,
I just finished upgrading from Symfony 2.8 to 3.4.6, and my http cache is broken when using
AppCache
(without debug).It seems that since this PR, when the session is started, the response cache is set to private, which is fine.
But now when I go to a page where session is started and where I do
render_esi(controller('MyBundle:Controller:action'))
, http cache is not working as before, because subrequests responses are made private even if I don't start / use the session.The text was updated successfully, but these errors were encountered: