2
votes

I am using restful controllers. I need to run some filters like auth and custom permissions on them. So I put them in a route group and set filters on that group. In addition I also want to run csrf filter but only on post requests. How to do this in the route group?

Added code for clarification

Route::group(array('before' => 'auth|allowed|csrf'), function() {
    Route::controller('controller', 'SomeController');
    Route::controller('othercontroller', 'OtherController');
});

I want the csrf only on post routes. I really don't want to add a filter on every controller (there are quite a few);

4

4 Answers

10
votes

You can do this from your controller when working with resourceful routing.

public function __construct() {
  $this->beforeFilter('csrf', array('on' => 'post'));
}
2
votes

You can create a custom filter that runs the standard CSRF filter, but only on POST requests like this...

Route::filter('csrfIfPost', function($route, $request) {
    if ($request->getMethod() == 'POST') 
        return $route->callFilter('csrf', $request);
});

Then anywhere you want to use it, just use the filter 'csrfIfPost' instead of 'csrf'.

1
votes

You can have groups inside a group:

Route::group(array('before' => 'session'), function()
{
    Route::get('/login', array('as'=>'login', 'uses'=>'LogonController@form'));

    Route::group(array('before' => 'csrf'), function()
    {
        Route::post('/login', array('as'=>'login.post', 'before' => 'csrf', 'uses'=>'LogonController@login'));

        Route::group(array('before' => 'permissions'), function()
        {
            Route::post('/store/checkout/new/shipping/address', array('as'=>'store.checkout.shipping.address.new',  'uses'=>'StoreController@newShippingAddress'));
        }
    }
}
1
votes

OK. I solved it i guess. I checked whether the request was post or not. Don't know whether this is bad practice. I changed the csrf filter in filter.php to

Route::filter('csrf', function()
{
    if (Request::getMethod() == 'POST' && Session::token() != Input::get('_token'))
    {
        throw new Illuminate\Session\TokenMismatchException;
    }
});