Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Hello,
I have found a strange behaviour of a finder today. It works perfectly for an admin and for an anonymous user. However when it comes to an authorized one I see the following message.
The form has become outdated. Copy any unsaved work in the form below and then reload this page.
Reproduction case.
- Create a content finder with an autocomplete widget.
- Create a user and being authorized as this user (not as an admin) try to search for a node using this finder.
Just in case my finder is here
$finder = new finder;
$finder->disabled = FALSE; /* Edit this to true to make a default finder disabled initially */
$finder->api_version = 2;
$finder->name = 'content_finder';
$finder->views_view = 'finder_node';
$finder->views_display = 'page_1';
$finder->title = 'Поиск по местам';
$finder->description = 'Поиск по названию места';
$finder->path = 'content-finder';
$finder->block = TRUE;
$finder->status = TRUE;
$finder->settings = array(
'search_tab' => 'node',
'block' => TRUE,
'form_on_page' => 0,
'find_button' => TRUE,
'find_text' => 'Find',
'go_button' => 0,
'go_text' => 'Go',
'ajax_effect' => 'none',
'show_results' => 'completed',
'results_style' => 'views',
'no_results' => 'default',
'pager' => 10,
'redirect' => 'always',
'element_logic' => 'AND',
'url' => 'enabled',
'url_delimiter' => ',',
'validate_empty' => 0,
);
$finder->elements = array(
'title' => (object) array(
'id' => 'title',
'finder' => 'content_finder',
'settings' => array(
'field_logic' => 'OR',
'value_logic' => 'AND',
'match' => 'e',
'fields' => array(
'node.title' => (object) array(
'table' => 'node',
'field' => 'title',
'relationship' => NULL,
),
),
'max_suggestions' => '15',
'autocomplete_field_logic' => 'OR',
'autocomplete_value_logic' => 'AND',
'autocomplete_match' => 'c',
'autocomplete_delimit' => ' ',
'autosubmit' => 1,
'size' => '60',
),
'title' => 'Поиск места',
'element' => 'autocomplete',
'weight' => '0',
),
);
Comments
Comment #1
Georgii CreditAttribution: Georgii commentedAnd one important note here. Everything is OK if
But if there are more than one non-admin user on the web-site - then it is a problem for avery user except of one of them. Let's say:
To me it looks like there is a hash value generated somewhere to validate a finder form and it is getting outdated for multiple users.
Comment #2
danielb CreditAttribution: danielb commentedIs this a block?
Comment #3
Georgii CreditAttribution: Georgii commentedYes it is. However, I have just checked that the same issue is with the form on a page. Can I help with debugging in any way?
Comment #4
danielb CreditAttribution: danielb commentedTry turning off caching at admin/config/development/performance
Cache pages for anonymous users
Cache blocks
Comment #5
danielb CreditAttribution: danielb commentedInteresting http://drupal.org/node/240828
doesn't help this though
Comment #6
danielb CreditAttribution: danielb commentedWhen you change users to test this, make sure you reload the finder form, in case you're just leaving a finder tab open and reusing it? Also make sure nothing gets cleared in the backend between loading the form and submitting it.
Comment #7
Georgii CreditAttribution: Georgii commenteddanielb, it looks like the "Cache blocks" is that bad guy. When this option is enabled (even if "Cache pages for anonymous users" is turned on) I see the problem described. When it's disabled - the issue is gone.
Comment #8
Georgii CreditAttribution: Georgii commentedI have an assumption that the form in a block hasa sort of a hash for validation purposes. And validation algorithm is different for anonymous users, registered users and admins. With admins and anonymous it works but for registerd ones this hash is cached and validation works only once...
Comment #9
danielb CreditAttribution: danielb commentedDrupal adds a #token thing (which is reflected in a hidden field) for registered users to prevent people tricking others into submitting a form for them, which is useful for stuff like node editing, or administration forms, but not really an issue in something like a finder form.
http://api.drupal.org/api/drupal/includes--form.inc/function/drupal_prep...
It is possible that adding
$form['#token'] = FALSE;
in finder_form() in finder/includes/form.inc might fix it?Comment #10
Georgii CreditAttribution: Georgii commenteddanielb, that worked like a charm!
finder/includes/form.inc
38: $form['#action'] = url($finder->path);
39: $form['#token'] = FALSE;
40: $form['finder_form'] = array(
Comment #11
danielb CreditAttribution: danielb commentedI've added that to the repository, it will appear in future releases. Thanks for testing it out!
Comment #12
Georgii CreditAttribution: Georgii commentedThanks for your support!
Comment #13
constantinejohny CreditAttribution: constantinejohny commentedHi, I am sorry to say this, but #10 did not help me :/
I am still getting these messages:
It only appears for users that are not logged in. I have a page, not a block. And cache is disabled on all the site.
Comment #14
K1T5UN3 CreditAttribution: K1T5UN3 commentedHello,
Using Finder 7.x-2.0-alpha6 and the default content-finder, I still encounter this issue when using the form as an anonymous user.
Same settings and error messages as #13.
Comment #15
constantinejohny CreditAttribution: constantinejohny commentedOK, I'm trying to fix this. When I edited #10 solution with this:
finder/includes/form.inc
it works OK. Was the # a typo, or was it really supposed to be there?
Comment #16
K1T5UN3 CreditAttribution: K1T5UN3 commentedOh I didn't even notice that. Indeed the # shouldn't be there, because a token is a form element, not a property.
Comment #17
danielb CreditAttribution: danielb commentedNo the # is supposed to be there. It is not a form element, if it was a form element it would be an array value with #properties of it's own, such as #type.
See the code in http://api.drupal.org/api/drupal/includes--form.inc/function/drupal_prep...
which checks '#token'.
It then removes #token, and therefore the code in drupal_validate_form() which produces those errors should not run.
So what you are saying is happening... should not happen.
Comment #18
K1T5UN3 CreditAttribution: K1T5UN3 commentedOk, my bad.
I took a quick look at the drupal_prepare_form function. The form token of the finder is not getting unsetted because the uid of the anonymous user is 0, so the
if (!empty($user->uid) && !$form_state['programmed'])
condition in this function doesn't validate.By manually unsetting the form token in finder/includes/form.inc, the error is gone. I don't know if it's the better way to fix the issue, though.
Comment #19
constantinejohny CreditAttribution: constantinejohny commentedWhen I used #token, it outputted an error that "Value fomr_token is not valid" which I don't get, it should have skipped this part of code when the #token was set to FALSE.
Now I am using token and everything works... Am using Drupal 7.10 and the new alpha version of Finder.
Comment #20
Georgii CreditAttribution: Georgii commentedLet me summarize:
It looks like the bug-fix for an authenticated user introduced problems for anonymous ones. If that's the case I think there should be additional "if" clause checking for
global $user
$user->uid
Not equal to 0 and only in that case do $form['token'] = FALSE;
I'm not able to check it now, but will try do to that in 6-7 hours.
Will keep you posted.
Comment #21
Georgii CreditAttribution: Georgii commentedHere is the final version that works for me in all cases (anonymous and authenticated users)
Comment #22
Georgii CreditAttribution: Georgii commentedComment #23
danielb CreditAttribution: danielb commentedThat makes sense to me Georgii.
Comment #24
danielb CreditAttribution: danielb commentedComment #26
dhallennem CreditAttribution: dhallennem commentedFor me, if someone have the same problem, it is because of the AuthCache module which unset the form['#token'].
Comment #27
Sneakyvv CreditAttribution: Sneakyvv commentedfor me $form['#token'] = FALSE didn't work
I dove into the core and found this
So it seems you would have to either
unset($form['#token'])
or
$form['#token'] = NULL
Comment #28
Jivan CreditAttribution: Jivan commented$neakyvv, you saved my day.
For information purposes :
This solution also works for a customized user profile form, and I suppose for every form that will show this error message.
I implemented hook_form_user_profile_form_alter() in my template.php to reconfigure user-profile-form, and also added a custom user-profile-form.tpl.php called by hook_theme().
Everything displayed correctly but after submit the form didn't validate anymore and this error message (the form has become outdated) was shown.
By adding $form['#token'] = NULL; in hook_form_user_profile_form_alter() everything works correctly now.
Thanx.
Comment #29
Mo Omar CreditAttribution: Mo Omar commentedI get the same message when a user tries to comment on a node when this user is not an admin. I am not using finder and my drupal version is 7.22
Can I apply the same solution? Can someone tells me where and what to do exactly? or should I open a new issue?
Comment #30
qqboy CreditAttribution: qqboy commented$form['#token'] = NULL
works not else in my case
@Sneakyvv great.
Comment #31
Bhuvana_Indukuri CreditAttribution: Bhuvana_Indukuri as a volunteer commented@Sneakyvv - You saved my day!
Comment #32
jyotisankar CreditAttribution: jyotisankar commentedHi
I am using Drupal version 7.41. I am facing the same issue "The form has become outdated. Copy any unsaved work in the form below and then reload this page." When I logged in as a different role other than administration and trying to create a different user from some other role getting this error message.
The codebase that I found in from.inc referring to the discussion above is :
function _drupal_invalid_token_set_form_error() {
$path = current_path();
$query = drupal_get_query_parameters();
$url = url($path, array('query' => $query));
// Setting this error will cause the form to fail validation.
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then reload this page.', array('@link' => $url)));
}
The above function is being called in
if (isset($form['#token'])) {
if (!drupal_valid_token($form_state['values']['form_token'], $form['#token']) || !empty($form_state['invalid_token'])) {
_drupal_invalid_token_set_form_error();
// Stop here and don't run any further validation handlers, because they
// could invoke non-safe operations which opens the door for CSRF
// vulnerabilities.
$validated_forms[$form_id] = TRUE;
return;
}
}
Can anyone help me out on this.
Thanks
Comment #33
trakinos CreditAttribution: trakinos commentedJust a quick update:
If you are using $hooks to theme a form, you have to put this code in the array:
Comment #34
alex_optimYou need only to make
unset($form['#token']);
in hook_form_alter.It works for me.
Comment #35
nitin.k CreditAttribution: nitin.k as a volunteer and commentedSetting form token to FALSE might be a solution but sometimes the function which you pass in "access callback" can lead to this error too.
Comment #36
danielb CreditAttribution: danielb commentedI suppose this needs looking at again. I haven't encountered the issue but unset/null would be an acceptable change to make if that resolves the issue for some people.
Comment #37
praveen_91 CreditAttribution: praveen_91 commentedhi, all
is it right to set unset($form['#token']); for drupal form security purpose ?
Comment #38
gjuliane CreditAttribution: gjuliane commentedThis works for me in my module.