どんな事でもお気軽にお問い合わせください
0120-803-656
24時間受付いたします

【CakePHP2.x】Securityコンポーネントを使用したときの不具合【black-holed】


開発チームの長谷です。

CakePHPでログイン機能を実装するため、Securityコンポーネントを使用していたら、
こんな謎のエラーが発生しました。

The request has been black-holed

ブラックホール?なんだこれは。。
特にフォーム送信後にブラウザで「戻る」をして、もう一回送信したりすると発生する。。。

まだペーペーの自分にはこのエラーがどういったものか分からなかったので、
とりあえず解決方法を調べてみることにしました。

PostやAjaxを許可する

フォーム画面でほぼほぼエラーが出ていたので、
beforeFilterでPostとついでにAjaxを許可するようにしました。

app/Controller/AppController.php

public function beforeFilter() {

	$this->Security->validatePost = false;
	$this->Security->csrfCheck = false;
        
 ...
	// ~なんらかの処理~
	
}

これでエラーが発生しなくなったかなと少し期待しつつ確認をしましたが
やっぱり、同じエラーが発生していた。
再び調査開始。

オーバーライドしているのを修正

AppController.phpのbeforeFilterでPostとAjaxを許可したことによって、
ControllerがbeforeFilterをオーバーライドしてしまい、
通信の許可がなくなってしまったらしい。

なので、black-holeエラーが発生するControllerを修正。
beforefilterにparent::beforeFilter();を追加します。

app/Controller/UserController.php

public function beforeFilter() {
	parent::beforeFilter();

	// ~なんらかの処理~
}

これでエラーが出なくなっただろうと思い、
確認してみましたが、再度同じエラーが発生。。

ブラックホールコールバックの処理

ここまできて何だが、公式サイトに対応方法が書いてありました。。

Security コンポーネントによって制限されている時、 デフォルトでは、不正なリクエストとして 400 エラーを返し破棄します。
コントローラ中のコールバック関数を $this->Security->blackHoleCallback に設定することによってこの振る舞いを変更できます。

つまり、フォーム送信後にブラウザで「戻る」をしてもう一度送信をするという行為が
不正なリクエストなので、
400エラーを返しblack-holedエラーが発生していたということになります。

最初から公式サイトを見ておけばよかった。。

というわけで、black-holeエラーが発生するControllerのbeforefilterを以下のように修正。

public function beforeFilter() {

	parent::beforeFilter();

	$this->Security->blackHoleCallback = 'blackhole';

	$this->Security->validatePost = false;
	$this->Security->csrfCheck = false;

	// ~なんらかの処理~
}

// ブラックホールをスルーする
public function blackhole($type) {
}

これで、black-holedエラーが出なくなりました!!
一安心。。

参考

https://book.cakephp.org/2.0/ja/core-libraries/components/security-component.html
http://www.aipacommander.com/entry/2015/04/27/180000


お問い合わせ 採用情報 エンジニアブログ
ISO27001認証
Contact PageTop
株式会社ビヨンド

© beyond Co., Ltd. All rights reserved.