Laravel 4在所有POST请求中使用CSRF保护

14

最近一直在了解 Laravel,试图理解他们所拥有的 CSRF 保护措施。但是我无法使其正常工作。是否可以通过 CSRF 过滤器验证所有提交的 post 请求?我看到 Laravel 系统中有:

    App::before(function($request)
{
    //
});
我该如何在CSRF过滤器中使用此功能?我已经尝试了几种不同的方法,例如
App::before(function($request)
{
    Route::filter('csrf','post');
});

但我可能完全错了...这会怎么运作?或者用这种方式做甚至是可能的吗?


3
请查看文档:http://four.laravel.com/docs/security,你会在页面中部找到答案 :) - Perry
顺便提一下,由于这仍然在Google的首页上,安全文档的最新版本是:http://laravel.com/docs/security。 - dhazelett
7个回答

30

这是最好的、最简单的解决方案:

Route::when('*', 'csrf', array('post'));

无需分组路由或搞乱构造函数。


@rotaercz In app/routes.php - EsTeGe

23

你可以使用路由组。这将应用指定的选项到在组中定义的任何路由:

Route::group(array('before' => 'csrf'), function()
{
    Route::post('/', function()
    {
    // Has CSRF Filter
    });

    Route::post('user/profile', function()
    {
    // Has CSRF Filter
    });

    Route::post(....);
});

对于某些路由,或者如果分组不是您想要的,您也可以使用模式过滤器:

//all routes beginning with admin, sent via a post http request will use the csrf filter
Route::when('admin/*', 'csrf', array('post'));

注意:这段代码应该放在你的routes.php文件中


我喜欢后面的过滤选项 - 但请注意,您的过滤器被称为crsf而不是csrf! - alexleonard

11

在我的BaseController中,我有以下代码:

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

拥有这样的App::before过滤器是一个有趣的方法,但我不知道哪个更好?


1
值得注意的是,如果您打算使用BaseController方法,您需要在控制器中添加parent::__construct(); - nielsstampe
1
没有使用 parent::__construct(); 对我来说实际上完全正常工作。添加它会导致 Symfony \ Component \ Debug \ Exception \ FatalErrorException: Cannot call constructor - Nick
太棒了。在Laravel 4.2中不需要添加parent::_contruct() - clod986

4

由于某些原因,放置

$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));

我尝试将代码插入BaseController.php中,但是它对我没有起作用;我使用了伪造的token进行测试。因此,我想出了以下解决方案:

routes.php:

Route::group(array('before' => 'csrf'), function() {
    Route::resource('areas', 'AreaController');
    Route::resource('usuarios', 'UsuarioController');
    // ... more stuff
});

filters.php(CSRF过滤器部分):

Route::filter('csrf', function()
{
    if ($_SERVER['REQUEST_METHOD'] === 'POST' || $_SERVER['REQUEST_METHOD'] === 'PUT') {
        if (Session::token() != Input::get('_token'))
        {
            throw new Illuminate\Session\TokenMismatchException;
        }
    }
});

这对我来说解决了问题。

4
这将允许您在应用的所有页面上对所有表单应用CSRF保护。
App::before(function($request)
{
    if ($request->getMethod() === 'POST') {
        Route::callRouteFilter('csrf', [], '', $request);
    }
});

注意:'post'是HTTP POST动词,因此它将涵盖Laravel的post、put、delete请求等。

0

您提供的代码仅创建了过滤器。您仍然需要在路由器或控制器中使用它(如果需要,甚至可以在基础控制器中使用)。

在我看来,在路由中使用过滤器是最好的选择。


0

只需将此代码添加到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')));
}

这将在所有的post、put、patch和delete请求中添加CSRF过滤器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接