Closed pavelsr closed 4 years ago
Oops, I can save you some time: The Form plugin isn't adding the CSRF token field.
Edit: No, I'm wrong, the form plugin is adding a CSRF token, so your form must not have one. You have to add one using the csrf_field
helper or the csrf_token
helper.
Sorry, I didn't understand. Where I need to add csrf_field
or csrf_token
?
My form processor controller looks like
my $user_route = app->routes->under( '/my', sub {
my ( $c ) = @_;
my $user = $c->yancy->auth->current_user;
$c->stash( user_id => $user->{id} );
return 1;
} );
$user_route->post( 'cars/create' )->to( 'yancy#set', schema => 'cars' );
If you use csrf_field
, it needs to be in the form so it gets sent with the request, like:
%= form_for carscreate => begin
%= csrf_field
... the rest of the form here ...
% end
If you can't use csrf_field
, if you're submitting the form through JS or something, you can get the token itself by using csrf_token
:
% use Mojo::JSON qw( to_json );
%= javascript begin
window.csrf_token = <%= to_json csrf_token() %>
% end
Ok, I understand that. But problem is that I generate form using Yancy::Plugin::Form::form_for
Simple demo of that error: https://gist.github.com/pavelsr/ab24ac5972df2ac9b6983e3b501252f6
I think something wrong with with CSRF validation code or with yancy/form/bootstrap4/form.html.ep
UPD: As quick fix I have to submit form data as JSON, but still please look the demo.
... Oh wow. It took me a couple hours, but I found the problem: The docs say to do app->yancy->form->form_for( ... )
, but that creates a new, blank controller object. So the form generates a new CSRF token for that new controller, which is not the correct CSRF token in the real controller object's session...
Changing the index.html.ep
template to use $c->yancy->form->form_for(...)
fixes the problem. I'm going to add some notes to the docs, fix some docs that have app->yancy->form
instead of $c->yancy->form
, and add a check in form_for
that verifies that the controller has an actual request when generating a CSRF token (and issuing a warning if it does not). I'll also add a way to disable CSRF just in case one finds the need to...
I got CSRF error during form processing.
Seems like error from this string.
How to debug the reason?