Laravel5では全てのPOSTに勝手にCSRFチェックが付いてきます。
便利と言えば便利ですが、Laravel外からのPOSTを受け取りたいときなど大迷惑です。
CSRFチェックを排除する方法が何故かなかなか見当たらなかったので調査結果を記載。
Kernel
デフォルトで適用されるミドルウェアはapp/Http/Kernel.php
に記載されています。'App\Http\Middleware\VerifyCsrfToken'
が書かれている行を削除するとCSRFチェックが無効化されます。
この場合、あらゆるフォームに対してCSRFチェックが無くなります。
特定のフォームに対して有効にしたい場合、コントローラのコンストラクタに
$this->middleware('App\Http\Middleware\VerifyCsrfToken');
と書けば、そのコントローラでは有効になります。
しかし、各メソッド内に書いても効かないようです。
つまり、同一コントローラ内のフォームAには有効に、フォームBには無効にしたいといったことができません。
さらにデフォルトが危険側に倒れるため、この設定は微妙。
VerifyCsrfToken
CSRFチェックの本体はapp/Http/Middleware/VerifyCsrfToken.php
です。
ここにCSRFチェックを無効にしたいフォームを記載することでどうにかします。
デフォルトのVerifyCsrfToken::handle()は
public function handle($request, Closure $next){
return parent::handle($request, $next);
}
とだけ書かれていましたが、ここを変更。
// CSRFを除外したいURLリスト
protected $routes = [
'hoge/fuga',
'foo/bar',
'baz/qux',
];
//url已经经过url()函数处理,不需要再处理
// handleを変更
public function handle($request, Closure $next){
if($this->excludedRoutes($request)){
return $this->addCookieToResponse($request, $next($request));
}
return parent::handle($request, $next);
} /*
* CSRFを除外したいURLであるかどうかをチェックする。
* @param Request リクエスト
* @return boolean CSRFを除外したいURLであればtrue
**/
protected function excludedRoutes($request){
foreach($this->routes as $route){
if ($request->is($route)){ return true; }
}
}
これで特定URLだけCSRFチェックを外すことができました。
一部のフォームを操作したいだけなのに、いちいち全体に影響のあるファイルを変更しないといけないのが微妙。
コントローラ
HogeController::postForm(){
$this->disableMiddleware('App\Http\Middleware\VerifyCsrfToken');
}
みたいなことはできんのか?
http://www.camroncade.com/disable-csrf-for-specific-routes-laravel-5/
这种问题只能用vpn查