-
- Notifications
You must be signed in to change notification settings - Fork 388
Description
Hi! Everything is ok but shouldn't there somewhere in LiveComponent documentation, somewhere where Forms tab is, maybe in new CSRF subtab there, be there very clearly written something like this: if you are using Symfony as default so with Turbo and with stateless csrf protection on your forms enabled and you are using LiveComponent that uses ComponentWithFormTrait then in Twig where you render your form you should render that hidden csrf _token input field by yourself like this: {{ form_widget(form._token, { attr: { 'data-model': 'norender|*' } }) }} because if you do not do that and you let Symfony render it for you it will cause TWO post requests on one submit button click. If I understand this correctly but I am rarely and sorry if this is the case here :P LiveComponent that uses ComponentWithFormTrait has $this->formValues which stores all form fields values and thanks to that when user interacts with form LiveComponent can detect change and rerender itself but the problem is that $this->formValues also contains this csrf _token value and it changes every time from "csrf-token" to some real value on form submit by csrf_protection_controller.js and its value now differers to that stored in $this->formValues so component rerenders itself and as a result there are TWO post requests on form submit, one request to form handler method (I am using normal Symfony controller in that case and not via live action) which is normal and expected but also the second request that comes after that which is LiveComponent rerendering itself but that should not be happening in that situation, on one submit there should one post request. This can sometimes cause HTTP500 responses for example if form is for entity edit only because there is no creating new ones in that app and it was removed it in form handler method which happened first and then that second request happens that should not be happening and that entity do not exists any more if I understand correctly, but for sure visible as red in Profiler or invalid csrf token value please try again errors. I thought it would be nice if something like this was clearly written somewhere in the documentation which in general is really great so I post this out here. Took me some time to figure it out but I am not sure I understand this correctly, and I never made pull request but also my English is not so good for writing documentation so I just let it know here. Regards
Update:
I was wrong. Adding data-model="norender|*" to csrf _token input do not help. It helps at first sight in that sense that after submit and csrf_protection_controller.js changes this _token value there is no rerender (as second request) so on submit there is one not two requests, so good, but that _token value in fact changed so problems occur later, after another user interaction with form, and when form rerenders later: "csrf token invalid, try resubmit" error.
But I found in documentation in live component (not in form section but in action section) that thanks to custom header, and cors, and same-origin I do not have to do anything against csrf. But only if that form submit is handled by live action? What in case when it is handled by normal Symfony controller? Would be great to have something about csrf in live component forms section there. Turbo request headers also have custom header and cors and same-origin so maybe yes...
I ended up changing submit handler from controller method to live action and disabling csrf for that one form that is inside live component. It seems like now there is everything working: 1) one post request on submit not two 2) no invalid csrf token errors 3) hopefully there is csrf protection like live action documentation says even if I disabled it on form.
Can someone please confirm that setting "csrf_protection => false" in form's configureOptions in fact do not disable it when that form is inside live component and live action handles submit and it is the correct way to do it?