I'm updating a Laravel 5.1 site to Laravel 5.2.39. I had a lot of issues with the "approved" upgrade process (in particular the middleware) so I ended up creating a new Laravel 5.2 site and just moving over my views, models and controllers from the old site. It seems to be working, except when I submit any form I get a token mismatch exception:
TokenMismatchException in VerifyCsrfToken.php line 67:
My forms have the token (using {{ csrf_field() }}) in them:
<div class="form-group">
{!! Form::label('name', 'Name') !!}
{!! Form::text('name', old('name'), ['placeholder' => 'Name', 'class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('email', 'Email') !!}
{!! Form::email('email', old('email'), ['placeholder' => 'Email', 'class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('phone', 'Phone') !!}
{!! Form::text('phone', old('phone'), ['placeholder' => 'Phone', 'class' => 'form-control']) !!}
</div>
{{ csrf_field() }}
<div class="form-group">
{!! Form::submit('Submit', ['class' => 'btn btn-default btn-small']) !!}
<input type="reset" class="btn btn-primary btn-small" />
</div>
and I have cleared my cookies and also tried setting the config/session.php lifetime to a higher number to ensure it's not timing out.
This is running on a homestead box.
Any ideas what to try?
EDIT: here's the route in question
Route::resource('contact', 'ContactController');
EDIT2: here's the route file. I don't believe it is required to wrap the routes in the web middleware in Laravel 5.2-- however, I've tried it both ways with the same error.
Route::group(['middleware' => ['web']], function () {
Route::get('/', 'AccountController#index');
Route::resource('account', 'AccountController');
Route::resource('contact', 'ContactController');
});
Dumping the $request->session()->token() in the controller's create action shows the current session token on the page with the form. This is the same token that is added to the form (checked with view source).
But when it gets to the Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::tokensMatch() class, I dump the session token and it's different than the form token-- meaning these will never match. Not sure what to expect here.
This is really annoying, but after everything else it appears this was a weird error caused by multiple Laravel sites on one Homestead box. I had set the session key differently and had cleared caches, but it still wasn't working.
Destroying the homestead box and rebuilding it appears to have fixed this issue. Thanks for all the comments and attempts at finding a solution.
Place your route within web Middleware. or in App\http\kernel copy all routes from web to protected $middleware array.
As long as you have your Form:open declaration, you no longer need the separate csrf_field line. Form::open should take care of it.
Are you using the laravel collective form package? The old illuminate package is no longer maintained.
As the previous user said, all routes also must be wrapped in the web middleware group, which also could be the problem.
Related
I am beginner at laravel. I want to use laravel collective (on laravel 9 version). And actually i want to use action. I write it in my blade:
{!! Form::open(['action' => 'PostsController#store', 'method' => 'POST']) !!}
{!! Form::close() !!}
and when i open it in browser it gives me error Action PostsController#store not defined.
i do not know. help me. i try to googled it but did not find. also i tried [PostsController::class] but not worked. i tried everything what i know
Best Solution - Using named routes
From documentation of Laravel Collectives you may come to know that you can use named routes in your code. So, we better use named route.
{!! Form::open(['route' => 'route.name', 'method' => 'POST']) !!}
{!! Form::close() !!}
Alternatives
You could either string including the namespace of controller with it to work
{!! Form::open(['action' => 'App\Http\Controllers\PostController#store', 'method' => 'POST']) !!}
{!! Form::close() !!}
or you could modify your RouteServiceProvider file and change the controller namespace there. protected $namespace = 'App\\Http\\Controllers'; this approach allows you to use 'ControllerName#method' controllers created in App\Http\Controllers directory.
The other way around is just call the route name.
<form action="{{ route('your.route.name') }}">
...
</form>
I'm starting from the blade password.blade.php which is loaded from the route
Route::get('password/email', 'Auth\PasswordController#getEmail')
->name('auth.password.email');
In the blade I have a form that I'm trying to post to the route:
Route::post('password/change', 'User\UserController#password')
->name('user.password.change');
Like so:
{!! Form::open(array('method' => 'POST', 'url' => route('user.password.change'))) !!}
<div class="form-group">
<label for="email">Email Address</label>
<input type="email" class="form-control" name="email" id="email" value="{{ old('email') }}">
</div>
<button type="submit" class="btn btn-primary btn-block">Send Email</button>
{!! Form::close() !!}
However, it seems like it's still posting to the 'password/email' route that gets the starting blade, if that makes sense.
How can I make sure that it posts to the user.password.change route?
route() must not be returning a URL
If you're not posting to the correct route, then route must be returning false or null. This would imply that you're not passing all the parameters necessary, or that there is a problem with the route in question. The question becomes, "Why?"
Routes Cache
One possibility is that the route cache needs to be updated. This can be done with the artisan command:
php artisan route:cache
Expected Passing User
The routes in the Question make it seems like this isn't the case, but if your UsersController function requires a User $user, you need to make sure your routes and form reflect that.
Assuming you're using an older version of Laravel or the Laravel collective. The issue is in your form open. You're not passing in the user for which you want to change the password, if your using Auth::user() you might not need to pass that parameter (Also, make sure the route checks that you're not changing the password on another account)
{!! Form::open(array('method' => 'POST', 'route' => ['user.password.change,'user'=>$user->id]])) !!}
OR
{!! Form::open(array('method' => 'POST', 'url' => 'user/' . $user->id . 'password/change'])) !!}
Avoid the Whole Mess
Also, unless you have a strong reason not to, you shouldn't need to make your own routes for authentication. Laravel has an auth package available you can add to any project that is running Laravel 5.4+.
i tried these two methods..
first one : MethodNotAllowedHttpException
Route::post('/settings/{id}/update/', 'HomeController#update');
Route::match(['put','patch'], '/settings/{id}/update/','HomeController#update') use this also..
{!! Form::model($user, ['method' => 'patch','action' => ['HomeController#update',$user->id]]) !!}
another one
{!! Form::model($user, ['method' => 'patch','route' => ['user.update',$user->id]]) !!}
please explain how to use route for update default auth users.
You should give a name to the route:
Route::patch('/settings/{id}/update/', 'HomeController#update')->name('user.update');
Or:
Route::patch('/settings/{id}/update/', ['as' => 'user.update', 'uses' => 'HomeController#update']);
I think you should just be specific about the method you want to use, be it put or patch and also If i remember correctly, if you have to use patch method referencing the answer from this post: Laravel form won't PATCH, only POST - nested RESTfull Controllers, MethodNotAllowedHttpException
<form method="POST" action="patchlink">
{!! method_field('patch') !!}
. . .
</form>
The method field is required because as I understood, Laravel uses this mechanism to handle patch request.
PS: What I just tried to highlight if I understood correctly is that, there should be an extra field to handle the patch method.
Hope this helps :)
After clicking in view,
{!! Form::open(['method' => 'GET', 'route' => ['city', $city->id]]) !!}
{!! Form::submit('Check', ['class' => 'btn btn-success']) !!}
{!! Form::close() !!}
system finds this route:
Route::get('city/{id}', 'CityController#show')->name('city');
which makes URL in web browser look like this:
http://localhost:8888/game/public/city/5?
problem is however, that when I click on another link for example:
<li>Reports </li>
I get URL in following format:
http://localhost:8888/game/public/city/home
instead of:
http://localhost:8888/game/public/home
Which is wrong since it doesn't work. How do I correct it?
Don't use relative URLs. You can use the url helper to generate a fully qualified url.
Home
Reference:
Laravel Docs - Helpers - url method
// routes.php
Route::resource('/image', 'ImageController');
Route::get('/create', 'ImageController#create');
Route::post('/store', 'ImageController#store');
// create.blade.php
{!! Form::open(array('url' => '/store', 'method'=>'POST')) !!}
.......
{!! Form::close() !!}
Here if i don't write these two lines (Route::get('/create', 'ImageController#create'); Route::post('/store', 'ImageController#store');)
The resource routing of create and store does not work and show some errors.
Why this happens? Thanks in advance.
When creating resource route you don't have to create individual routes. Because all RESTfull default routes will be created for you automatically.
You just need following route
Route::resource('image', 'ImageController');
then change form as below
{!! Form::open(array('route' => array('image.store'))) !!}
.......
{!! Form::close() !!}
Read More