-
-
Notifications
You must be signed in to change notification settings - Fork 520
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
CSRF token mismatch full cache strategy #10801
Comments
The problem also occurs when doing the opposite with the application languages. If I access English first and then Spanish and go back to English, it returns the messages in Spanish. It depends on the first page I cache. I've been debugging and it comes from this function in public function validateResolved()
{
// If this was submitted from a front-end form, we want to use the appropriate language
// for the translation messages. If there's no previous url, it was likely submitted
// directly in a headless format. In that case, we'll just use the default lang.
$site = ($previousUrl = session()->previousUrl()) ? Site::findByUrl($previousUrl) : null;
return $this->withLocale($site?->lang(), fn () => parent::validateResolved());
} |
You shouldn't need to wrap the form in the Are you using the native |
Now I was testing locally and I am not getting the CSRF mismatch error. I was watching production. I'll see if the token expires and try again to show you the error. But it keeps happening that when a page is cached, whether it is English or Spanish, and I submit a form, I get error messages for the wrong language. |
That's with the How are you submitting the forms? With an AJAX request or just a normal |
Yes, exactly. If I access the English form without having any page cached, I get the error messages in English. If I go to Spanish and submit the form, I get the error messages in Spanish. Now once both are cached, if I go back to the English form, I get the Spanish messages. The same thing happens in a different order. |
How are you submitting the form? Are you using AJAX? |
I'm using precognition. It's the peak studio component but I've extracted the form submission to a dedicated js file. This is my sending.js: export default () => ({
success: false,
submitted: false,
form: null,
init() {
this.form = this.$form(
'post',
this.$refs.form.getAttribute('action'),
JSON.parse(this.$refs.form.getAttribute('x-data')).form,
{
headers: {
'X-CSRF-Token': {
toString: () => this.$refs.form.querySelector('[name="_token"]').value,
}
}
}
)
},
submit() {
this.submitted = true
this.form.submit()
.then(response => {
this.form.reset()
this.$refs.form.reset()
this.success = true
this.submitted = false
setTimeout(() => {
this.success = false
}, 4500)
})
.then(this.$refs.form.scrollIntoView())
.catch(error => {
const summary = document.querySelector('#summary')
if (summary) {
this.$focus.focus(summary.querySelector('a'))
}
else {
console.log(error)
}
})
}
}); |
When you visit one of your cached form pages, do you see an AJAX request to |
If I load a page cached, I can see: When send the form to: |
@duncanmcclean I create a new project if you need test error: https://github.com/danielreales7/test-cache-form I did a clean installation of Statamic 5 (with Peak Studio) without any configuration. If you try to send the form with all the fields empty, it shows the error messages correctly. If you now add STATAMIC_STATIC_CACHING_STRATEGY=full to the .env, you cache the page, once cached, try to delete cookies from the browser and try to send the form. You will see in the console: |
Grabacion.de.pantalla.2024-10-02.a.las.22.00.51.movI am attaching a video of something I just realized. If it is sent without being cached, it shows the errors. When it is cached and I delete cookies, it does not show the errors. However, if I write on any input and send the form again, it shows the errors again. |
It seems when a page is cached and you submit an empty form you get a token mismatch error. As soon as you start filling in fields stuff kicks back in. |
Is it possible you're submitting before the nocache JS has run and replaced the csrf token in the form? |
No. Nocache is loaded before submitting the form. If I don't use cache it works fine. |
Bug description
If I don't use the full cache strategy on my site, the forms work fine. The problem comes when they are used. If I try to send the form, I get the following: CSRF token mismatch.
It seems that the token is not being updated behind the scenes.
I tried wrapping the form with a {{ nocache }} and it was fixed.
Then I realized that if I send the form in Spanish without filling in the inputs, I get the error messages in Spanish. So far so good. If I go to the English site and send it, it shows me the messages in English. Also good. But if I go back to Spanish, it shows me the English messages.
According to the documentation, if full cache is used, we must use {{ nocache }} https://statamic.dev/static-caching#csrf-tokens
Same here: https://statamic.dev/forms#caching
How to reproduce
Enabling the full cache strategy and multisite.
Logs
No response
Environment
Installation
Starter Kit using via CLI
Additional details
No response
The text was updated successfully, but these errors were encountered: