There is my problem, i need to submit forms in several steps. I have an app form and a login form
<form id="app_form" action="{{ path('app_create') }}" method="post" {{ form_enctype(formApp) }}>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.name, 'Name'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.name, { required : true }) }}</div>
<div class="span2" id="error_app_name">{{ form_errors(formApp.name) }}</div>
</div>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.description, 'Description'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.description, { required : true }) }}</div>
<div class="span2">{{ form_errors(formApp.description) }}</div>
</div>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.iosUrl, 'iOS'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.iosUrl) }}</div>
<div class="span2">{{ form_errors(formApp.iosUrl) }}</div>
</div>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.androidBundle, 'Android Bundle'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.androidBundle) }}</div>
<div class="span2">{{ form_errors(formApp.androidBundle) }}</div>
</div>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.wpUrl, 'Windows Phone'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.wpUrl) }}</div>
<div class="span2">{{ form_errors(formApp.wpUrl) }}</div>
</div>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.bbUrl, 'Blackberry'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.bbUrl) }}</div>
<div class="span2">{{ form_errors(formApp.bbUrl) }}</div>
</div>
<div class="row-fluid">
<div class="span2">{{ form_label(formApp.fallbackUrl, 'Fallback Url'|trans) }}</div>
<div class="span4">{{ form_widget(formApp.fallbackUrl) }}</div>
<div class="span2">{{ form_errors(formApp.fallbackUrl) }}</div>
</div>
{{ form_rest(formApp) }}
<button type="submit" class="btn">{{ 'Next step'|trans }}</button>
</form>
<form id="form_login">
<input type="hidden" id="login_csrf_token" name="_csrf_token" value="{{ csrf_token }}" />
<label for="login_username">{{ 'security.login.username'|trans({}, 'FOSUserBundle') }}</label>
<input type="text" id="login_username" name="_username" value="{{ last_username }}" required="true" />
<label for="login_password">{{ 'security.login.password'|trans({}, 'FOSUserBundle') }}</label>
<input type="password" id="login_password" name="_password" required="true" />
<input type="checkbox" id="login_remember_me" name="_remember_me" value="on" />
<label for="login_remember_me">{{ 'security.login.remember_me'|trans({}, 'FOSUserBundle') }}</label>
<button type="submit" class="btn">{{ 'Login'|trans }}</button>
<button class="btn" id="register_show" type="button">{{ 'Want to register ?'|trans }}</button>
<div id="error_login"></div>
</form>
I want to submit the login form en ajax and then submit the app form, but when i do that i’ve got an error
The CSRF token is invalid. Please try to resubmit the form
The Javascript code :
$('#form_login').submit(function(){
event.preventDefault();
$.post('./login_check', { _csrf_token : $('#login_csrf_token').val() ,
_username : $('#login_username').val() ,
_password : $('#login_password').val(),
_remember_me : $('#login_remember_me').val() },
function (data) {
console.log(data);
/**
* If the login was ok we submit the app form
*/
if(data.success){
$('#app_form').submit();
}
/**
* Else we sow to the user the error
*/
else{
$('#error_login').html(data.message);
}
}
);
});
The login form return success, but when i submit the app form $(‘#app_form’).submit(); the error appears in the next page.
Thanks in advance 🙂
The CSRF token uses, in part, cookies. When you generate two CSRFs on one page and submit one of the forms, you’re invalidating the cookie.
Without some extensions on the framework itself, I can only really see one way around this — and it’s rather roundabout:
What you could do is set up a controller that generates your app form.
At the initial page load, your controller will load the login form as well as the app form. Upon submitting the login form via AJAX, you’ll also request ONLY the controller for the app form (which will also give the user a new cookie). With javascript, you could then extract the NEW csrf token from the new form and inject it into the original app form. Then, when you submit the app form, it should have a new, valid csrf token.
To illustrate:
Get app form and login form -> submit login via AJAX -> get app form via AJAX in background -> steal new app form’s csrf token and inject it into first app form -> submit app form.