How to solve The CSRF token is invalid - symfony

Error
The CSRF token is invalid. Please try to resubmit the form.
This error appearing sometimes in symfony2 forms , but after refreshing form saved succesfully.
This error is not frequrent it happening sometimes while saving form.
I have tried in every browser issue is same.
On Refresh of Page Token get refresh in hidden input fields But error remains the same.
i have googled and found some helpfull article which suggest
{{form_rest(form)}}
to use before closing of form tag.
Here is my code
Twig code
<div id="{{ formID }}_container" class="main">
<div class="page">
<div id="{{ formID }}_output"></div>
{% include 'Bundle:Form:required_msg.html.twig' %}
{{form_start(form, { 'attr' : { 'id': formID } })}}
<div style="display: none">
{{form_rest(form)}}
</div>
{{form_end(form)}}
</div>
</div>
I have this hidden field:
<input id="form_id" name="details_form[_token]" value="somevalue" type="hidden">
This is my form data:
details_form[_token] value
details_form[age]
details_form[gender] F
This is the request response:
{"success":false,"msg":"Form is invalid.","errors":[{"name":"[0]","message":"The CSRF token is invalid. Please try to resubmit the form."}]
Some other answer I've seen on Stack Overflow (The CSRF token is invalid. Please try to resubmit the form) says to do this:
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'options' => array(),
csrf_protection' => false
));
}
But, my mequirement is not to set the csrf_protection flag to false. Can anyone suggest the best to way to handle this issue?

Related

Missing required parameters for [Route: {$route->getName()}] [URI: {$route->uri()}]."

in new to laravel and Im trying to set up an edit blade using resource controller . ( using laravel 5.7) but it is throwing an error like this
Missing required parameters for [Route: home.hotels.update] [URI: home/hotels/{hotel}]. (View: C:\xamp\....\.....\edit.blade.php)
Please note:
when i hover over edit button it is correctly pointing to the id's and
when i tries to echo a fieldname inside my "edit function"in controller it returns the correct page but "blank" . can some one tell me wher this error comming from and if possible how to fix this
code in my index blade ( part relating to the edit)
#foreach($hotels as $c)
<tr>
<td>{{$c->hotelid}}</td>
<td>{{$c->hotelname}}</td>
<td>{{$c->city}}</td>
<td>{{$c->location}}</td>
<td>{{$c->singleroom}}</td>
<td>{{$c->doubleroom}}</td>
<td>{{$c->deluxroom}}</td>
<td>{{$c->deluxdouble}}</td>
<td>{{$c->superiorsuit}}</td>
<td><a href="{{route('home.hotels.edit',$c->id)}}"class="btn btn-info" >Update </a>
my edit blade
im passing the entries like this
<form method="post" action="{{route('home.hotels.update',$hotels->id)}}">
#csrf
{{ method_field('PUT') }}
<div class="form-group">
<div class="row">
<label class="col-md-6">Hotel ID</label>
<div class="col-md-6"><input type="text" name="hotelid" class="form-control" value="{{$hotels->hotelid}}"> </div>
</div>
......... rest of the input fields follows........
controller functions
public function index()
{
$arr['hotels']=hotels::all();
return view('admin.hotels.index')->with($arr);
}
my update function also has the same code as store ------
public function store(Request $request, hotels $hotels)
{
$hotels->hotelid=$request->hotelid;
$hotels->hotelname=$request->hotelname;
...........other fields..................
$hotels->save();
return redirect('home/hotels');
}
public function edit(hotels $hotels )
{
$arr['hotels'] = $hotels;
return view('admin.hotels.edit')->with($arr);
}
and my routes
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('home/users', 'Admin\UsersController',['as'=>'home']);
Route::resource('home/hotels', 'Admin\HotelsController',['as'=>'home']);

How to dynamically set 'was-validated' class on form to show validation feedback messages with angular 5 after submit

I am using a template based form in angular. I also use bootstrap (v4) and I wish to show some validation messages when the form was submitted.
This is my form:
<form [ngClass]="{'was-validated': wasValidated}">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" class="form-control" [(ngModel)]="category.name" #name="ngModel" required maxlength="100"/>
<div *ngIf="name.invalid" class="invalid-feedback">
<div *ngIf="name.errors.required">
Name is required.
</div>
</div>
</div>
<button type="submit" class="btn btn-success" (click)="save()">Save</button>
</form>
My component looks as follows:
category: Category;
wasValidated: boolean = false;
ngOnInit() {
this.reset();
}
save() {
this.wasValidated = true;
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
}
reset() {
this.wasValidated = false;
this.category = {} as Category;
}
This works, but I have a feeling it's overly complex and more like a workaround rather than the right way. What is the best way to accomplish this?
Note: the class was-validated must be present on the form element in order to show the div with class invalid-feedback. I'm using this: https://getbootstrap.com/docs/4.0/components/forms/#validation
Note 2: I have currently no mechanism yet to prevent form submission on error. I'd like to know a good solution for that as well!
With the answer from #Chellappan V I was able to construct the solution I wanted.
I have applied to following changes:
First added #form="ngForm" to the form tag in the template. Secondly I changed the ngClass expression to reference the submitted state of the form, rather than referring to a boolean which was set to true manually when form was submitted. Last but not least I pass the form in the submit method on the save button.
<form novalidate #form="ngForm" [ngClass]="{'was-validated': form.submitted}">
<!-- form controls -->
<button type="submit" class="btn btn-success" (click)="submit(form)">Save</button>
</form>
In the component I injected the template variable in the component with #ViewChild.
#ViewChild("form")
private form: NgForm;
The submit method now takes a form parameter of type NgForm which is used to check if the form was valid before sending a request to the backend:
submit(form: NgForm) {
if (form.valid) {
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
} else {
this.notificationService.add(notifications.validation_errors);
}
}
Finally the reset method resets the form and the model so it can be re-entered to submit a next instance:
reset() {
this.form.resetForm();
this.category = {} as NewCategoryDto;
}

CSRF token missing

That's something driving me crazy.
Take these snippets of code
class CommonController extends Controller
{
/**
* Create delete form
*
* #param int $id
*
* #return Form
*/
protected function createDeleteForm($id)
{
return $this->createFormBuilder(['id' => $id])
->add('id', \Symfony\Component\Form\Extension\Core\Type\HiddenType::class)
->getForm()
;
}
}
and
{% if delete_path is defined %}
<form id="delete" action="{{ path(delete_path, {id: entity.id}) }}" method="POST" class="pull-right" style="margin-top: -43px; margin-right: 10px;">
{{ form_widget(deleteForm) }}
<button type="submit" class="btn btn-default">{{ delete_form_submit_button|trans }}</button>
</form>
{% endif %}
Please pay attention, that's not pseudo-code, is real code I've found into an application a friend of mine asked me to fix.
My question is ... why CSRF token isn't showed in the view?
As a result my form submission are always invalid due to csrf token missing
More details
Symfony version: 2.8
Even if I use form_rest token still not be there so it's seems like is not generated at all but, under the hood, it should have been there (isValid())
EDIT
If I dump deleteForm, _token is there but if I try to use form_widget or form_row or form_rest it is not showed
If I don't use form_widget(deleteForm) or form_row(deleteForm.id), the token in showed.

How to pass data from twig to Symfony2 controller using form

I would like to know if there is a method to pass some variables (text from textarea) from Twig to Symfony2 controller via form.
<form action="{{ path('admin_core_save') }}" method="post">
<div id="edit-template">
{% if template.getData() is defined %}
<textarea id="template">{{ template.getData() }}</textarea>
{% endif %}
</div>
<input type="submit" value="Save" />
</form>
When I press save button it is going to saveAction() method
public function saveAction(Request $request)
{
var_dump($request);
return new Response('abc');
}
but response does not contain any textarea text. Is there a way to get this there?
I know I can build form inside the controller and send it to Twig, but I would like to know if this way is possible.
you can access POST values through request object like:
$this->get('request')->request->get('name');
I'm sure you have to learn a bit about Symfony2 Form Component. You will find that symfony already has built-in system for rendering forms handling user data posted through them.
Answering your question. There is a Request object that provides you full access to all request data, including POST variables.
To access POST values use Request::get() method:
$request->get('variable_name');
To pass any data to the twig template, use TwigEngine::renderResponse
$this->container->get('templating')->renderResponse('AcmeDemoBundle:Demo:template.twig,html',
array(
'someVar' => 'some value'
)
);
This var will be avaliable in your template as:
{{ someVar }}

symfony2 CSRF invalid

Okay, so today I updated my database with new information from our 'live' database... And since then I've been having issues on one of my forms. If you need any code let me know and i'll edit this and post the code needed...
I have a report form which has a date range field and a drop down for an agent department. When I first visit the page I see this at the beginning of the form:
The CSRF token is invalid. Please try to resubmit the form
So I go over to one of my other forms that has the same type of information, and check the _token out and this is what comes out:
<input type="hidden" id="ecs_crmbundle_TimeClockReportType__token" name="ecs_crmbundle_TimeClockReportType[_token]" value="87e358fbc4d6d3e83601216b907a02170f7bcd92" />
<input type="hidden" id="ecs_crmbundle_SimpleSalesReportType__token" name="ecs_crmbundle_SimpleSalesReportType[_token]" value="87e358fbc4d6d3e83601216b907a02170f7bcd92" />
The first one is the one that shows the error, and the SimpleSalesReport does not... Any idea why this is doing this or how I can fix it?
Thanks..
Are you by chance using $form->bindRequest() in the action which produces the CSRF error? I had this issue. You should not be binding the request for a new form. If you are posting the form to the same action, wrap the bindRequest in a conditional which checks if method is POST:
if ($this->getRequest()->getMethod() == 'POST') {
$form->bindRequest($this->getRequest());
if ($form->isValid()) {
...
}
}
There is no problem using {{ form_widget(form) }} to build your custom form.
All you have to do is add the _token like this:
{{ form_widget(form._token) }}
This error had me crazy for days!
Thanks krishna!
If in your form template you choose to not use the default form behavior {{ form_widget(form) }} you SHOULD put {{ form_rest(form) }}
Hope this could help anyone else!

Resources