所有 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 Inapp/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