Been looking into laravel lately, and trying to figure out the CSRF protection that they have. However, i can't get it work. Is there any way i can validate all post request submitted, with the CSRF filter? I've seen that the laravel system has:
App::before(function($request)
{
//
});
How would i be able to use this with the CSRF filter? Been trying a few different things like
App::before(function($request)
{
Route::filter('csrf','post');
});
But i'm probably way off here.. how would this work? or is it even possible doing it this way?
This is the best and the simplest solution:
Route::when('*', 'csrf', array('post'));
No need to group routes or to mess with constructors.
You can use route groups. This will apply the specified options to any routes defined in a group:
Route::group(array('before' => 'csrf'), function()
{
Route::post('/', function()
{
// Has CSRF Filter
});
Route::post('user/profile', function()
{
// Has CSRF Filter
});
Route::post(....);
});
For certain routes, or if grouping isn't what you want, you can also use a pattern filter:
//all routes beginning with admin, sent via a post http request will use the csrf filter
Route::when('admin/*', 'csrf', array('post'));
NOTE: this code would go in your routes.php file
In my BaseController I have this:
public function __construct()
{
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
$this->beforeFilter('ajax', array('on' => array('delete', 'put')));
}
Having such App::before
filter is an interesting approach but I don't know which is better?
For some reason putting
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
into BaseController.php didn't work for me; I did the test with fake tokens. So i came with the following solution:
routes.php:
Route::group(array('before' => 'csrf'), function() {
Route::resource('areas', 'AreaController');
Route::resource('usuarios', 'UsuarioController');
// ... more stuff
});
filters.php (csrf filter section):
Route::filter('csrf', function()
{
if ($_SERVER['REQUEST_METHOD'] === 'POST' || $_SERVER['REQUEST_METHOD'] === 'PUT') {
if (Session::token() != Input::get('_token'))
{
throw new Illuminate\Session\TokenMismatchException;
}
}
});
That did the trick for me.
This will allow you to apply CSRF to all forms across all pages of your app
App::before(function($request)
{
if ($request->getMethod() === 'POST') {
Route::callRouteFilter('csrf', [], '', $request);
}
});
Note: 'post' is the HTTP POST verb - so it will cover Laravel post, put, delete requests etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With