简体   繁体   中英

Laravel 4 CSRF on all POST requests

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.

The code you provided only creates the filter. You still need to use it in either your ROUTER or CONTROLLER (even in the basecontroller if need be).

In my opinion, using the filter in your ROUTES is the best place to use it.

Simply add this to the BaseController .

// Be sure to call parent::__construct() when needed
public function __construct()
{
    // Perform CSRF check on all post/put/patch/delete requests
    $this->beforeFilter('csrf', array('on' => array('post', 'put', 'patch', 'delete')));
}

This add the CSRF filter to all post, put, patch and delete request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM