所有 POST 请求上的 Laravel 4 CSRF

Posted

技术标签:

【中文标题】所有 POST 请求上的 Laravel 4 CSRF【英文标题】:Laravel 4 CSRF on all POST requests 【发布时间】:2013-06-24 04:12:43 【问题描述】:

最近一直在研究 laravel,并试图找出他们拥有的 CSRF 保护。但是,我无法让它工作。有什么方法可以使用 CSRF 过滤器验证所有提交的帖子请求?我看到laravel系统有:

    App::before(function($request)

    //
);

如何将它与 CSRF 过滤器一起使用?一直在尝试一些不同的东西,比如

App::before(function($request)

    Route::filter('csrf','post');
);

但我可能已经离开这里了.. 这将如何工作?或者甚至可以这样做吗?

【问题讨论】:

查看文档:four.laravel.com/docs/security 你会在页面中间找到你的答案 :) FWIW,由于这仍然在 Google 的首页,最新版本的安全文档是:laravel.com/docs/security 【参考方案1】:

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

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

无需对路由进行分组或与构造函数混淆。

【讨论】:

@rotaercz In app/routes.php【参考方案2】:

您可以使用路由组。这会将指定的选项应用于组中定义的任何路由:

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!【参考方案3】:

在我的 BaseController 我有这个:

public function __construct()

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

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

【讨论】:

值得补充的是,如果您打算使用 BaseController 方法,则需要将 parent::__construct(); 添加到您的控制器中。 如果没有parent::__construct();,它实际上对我来说绝对没问题。添加它会导致Symfony \ Component \ Debug \ Exception \ FatalErrorException: Cannot call constructor 太棒了。无需在 Laravel 4.2 中添加 parent::_contruct()【参考方案4】:

由于某种原因

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

进入 BaseController.php 对我不起作用;我用假令牌做了测试。所以我提出了以下解决方案:

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;
        
    
);

这对我有用。

【讨论】:

【参考方案5】:

这将允许您将 CSRF 应用于应用程序所有页面的所有表单

App::before(function($request)

    if ($request->getMethod() === 'POST') 
        Route::callRouteFilter('csrf', [], '', $request);
    
);

注意:'post' 是 HTTP POST 动词 - 所以它将涵盖 Laravel 的 post、put、delete 请求等。

【讨论】:

【参考方案6】:

您提供的代码仅创建过滤器。您仍然需要在 ROUTER 或 CONTROLLER 中使用它(如果需要,甚至在基本控制器中)。

在我看来,在 ROUTES 中使用过滤器是使用它的最佳场所。

【讨论】:

【参考方案7】:

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

这会将 CSRF 过滤器添加到所有 post、put、patch 和 delete 请求。

【讨论】:

以上是关于所有 POST 请求上的 Laravel 4 CSRF的主要内容,如果未能解决你的问题,请参考以下文章

cpanel 上的 Laravel POST 请求有时会返回 405 错误

Ajax Post Laravel 共享主机上的 403 错误

Laravel 4 使用数据从控制器向外部 url 发出 post 请求

PUT 请求 Laravel 上的 MethodNotAllowedException

如何在 Vue.js 和 Laravel 5.4 中发出 POST 请求

发出 POST 请求时出现推送错误的 Laravel WebSocket