Login to any Drupal site fails if the following circumstances come together:
- core caching feature for anonymous users switched on
- login form being submitted via Ajax
- more than one user wants to login since FAPI has created and stored the form in cache
How to reproduce:
- adjust the settings in Drupal: enable caching and make the login form being submitted via Ajax
- Open the page http://www.example.com/user from two separate browsers
- Reload those pages as often as you like, you can verify in html source of the pages in both browsers, that the form-build-id has the same value
- Now login to the site from one of those browsers. That should work fine.
- After that (!), login from the other browser without reloading the page before doing that. This login attempt will fail. You will fine a record in watchdog that says 'Invalid form POST data'.
Another check, if you turn off Ajax submission for that form, the exact same scenario will not cause that problem.
The behaviour is down to ajax_get_form() which deletes the cached record of the form straight after loading it from cache. This is why subsequent calls to the same function with the same form-build-id will then fail as the record is no longer available in cache.
The function drupal_get_form() which is used without Ajax is not deleting the record from cache after having loaded it and that's why the behaviour is different.
To resolve this problem I can see two options:
- Either do cache forms always individually, so that each delivered instance of a form has its own form-build-id
- Or do not delete the form from cache when going through ajax_get_form()
But I'm not sure which one is the "correct" one as I can't oversee possible side effects at this point.
For now, someone who understands this better needs to decide what's the best approach.
User interface changes
Don't think any would arise from fixing this.
Original report by jurgenhaas
When Drupal's core caching feature is switched on, forms are delivered to anonymous visitors from cache which results in the situation where one and the same form gets delivered more than once with the same form_build_id.
As soon as one of the anonymous users submits such a form, the record gets removed from cache.
The next visitor who is submitting the same form will potentially run into trouble because of the missing form record in cache.
The regular Drupal FAPI seems to be OK with that but if the form gets submitted via Ajax, the submission gets rejected, a watchdog entry gets issued ('Invalid form POST data') and drupal_exit() gets called.
The result of that is that the user would have to reload the page before being able to submit the form. This can be annoying i.e. if the form being used is the user login form. It seems as if just nothing is happening.
This issue arrises always when page caching for anonymous users and form submission via Drupal's own ajax mechanism get used in combination.
Enabling 'cache pages for anonymous users' results in the following behavior :
Login as user 'foo'. Login successful.
Login as another user 'bar'. Results in "Invalid form POST data'.
logout as user'foo'. try to re-login. Results in "Invalid form POST data'.
Disabling caching allows normal login.
I am a newbie to drupal, so it is entirely possible i have done something wrong. In that case pl. close the issue with my apologies.
In the firebug,the unsuccessful login attempts record a "200 OK" response.
Also clearing the cache in the admin menu, allows for one more login after which the issue persists again.
(P.S: In trying to reproduce this in the demo page, i noticed a minor issue: if an user name is already taken, one is not able to change the user name and login in the same form).