プロジェクトでセキュリティコンポーネントを使用していますが、開発中にエラーに関する詳細な説明を取得する方法はありますか?例:-cakephpのformメソッドを使用せずにビューにフィールドを追加すると、blackHoleCallback関数で「auth」としてエラーが返されます。代わりに、それがそのエラーを返した理由を説明する必要があります。問題を修正するのに非常に時間がかかるからです。詳細なエラーの説明を取得する方法はありますか?
4 に答える
あなたがしなければならないのは正しい場所を見るだけです
app/tmp/logs/error.log
ファイルを確認してください
エラーログを見ると、次のようなエントリが表示されます。
2013-03-16 17:24:29 Error: [BadRequestException] The request has been black-holed
#0 root/lib/Cake/Controller/Component/SecurityComponent.php(228): SecurityComponent->blackHole(Object(FacebookUsersController), 'csrf')
#1 [internal function]: SecurityComponent->startup(Object(FacebookUsersController))
#2 root/lib/Cake/Utility/ObjectCollection.php(130): call_user_func_array(Array, Array)
#3 [internal function]: ObjectCollection->trigger(Object(CakeEvent))
#4 root/lib/Cake/Event/CakeEventManager.php(246): call_user_func(Array, Object(CakeEvent))
#5 root/lib/Cake/Controller/Controller.php(670): CakeEventManager->dispatch(Object(CakeEvent))
#6 root/lib/Cake/Routing/Dispatcher.php(183): Controller->startupProcess()
#7 root/lib/Cake/Routing/Dispatcher.php(161): Dispatcher->_invoke(Object(FacebookUsersController), Object(CakeRequest), Object(CakeResponse))
#8 root/app/webroot/index.php(96): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
#9 {main}
画面に表示されているエラーを読みます
デバッグモードの場合、このエラーはエラーが発生したときに画面にも表示されます。例えば:
The request has been black-holed
Error: The requested address '/admin/fooby/edit/1' was not found on this server.
Stack Trace
CORE/Cake/Controller/Component/SecurityComponent.php line 228 → SecurityComponent->blackHole(FacebookUsersController, string)
[internal function] → SecurityComponent->startup(FacebookUsersController)
CORE/Cake/Utility/ObjectCollection.php line 130 → call_user_func_array(array, array)
[internal function] → ObjectCollection->trigger(CakeEvent)
CORE/Cake/Event/CakeEventManager.php line 246 → call_user_func(array, CakeEvent)
CORE/Cake/Controller/Controller.php line 670 → CakeEventManager->dispatch(CakeEvent)
CORE/Cake/Routing/Dispatcher.php line 183 → Controller->startupProcess()
CORE/Cake/Routing/Dispatcher.php line 161 → Dispatcher->_invoke(FacebookUsersController, CakeRequest, CakeResponse)
APP/webroot/index.php line 96 → Dispatcher->dispatch(CakeRequest, CakeResponse)
csrfエラーの処理
特定のエラーの詳細(つまり、投稿しているデータ、およびその時点でのセッションの正確なトークンデータ)を使用すると、それがない場合に、ここで発生した問題に答えることができます。
エラーをスローしている行を見てください。
上記のスタックトレースでは、エラーの原因は次のとおりCORE/Cake/Controller/Component/SecurityComponent.php line 228
です。ファイルを開き、そのコードが何であるかを確認します。
if ($isPost && $isNotRequestAction && $this->csrfCheck) {
if ($this->_validateCsrf($controller) === false) {
return $this->blackHole($controller, 'csrf');
}
}
これから明らかなことは、関数_validateCsrf
がブラックホール化された要求に責任があるということです。これはそれほど驚くべきことではありません。
その関数のソースを見てください:
protected function _validateCsrf(Controller $controller) {
$token = $this->Session->read('_Token');
$requestToken = $controller->request->data('_Token.key');
if (isset($token['csrfTokens'][$requestToken]) && $token['csrfTokens'][$requestToken] >= time()) {
if ($this->csrfUseOnce) {
$this->Session->delete('_Token.csrfTokens.' . $requestToken);
}
return true;
}
return false;
}
その関数がfalseを返す理由に応じて、デバッグを続行する方法を決定します。
コンポーネントの正しい構成
CSRFエラーのデバッグの必然的な結果は、セキュリティコンポーネントの構成を変更する必要があることです。
たとえば、アプリがページの読み込みの間に同じフォームを複数回送信しているため、トークンを再利用したいですか?
フォームデータに新しいフィールドを追加して、フォームリクエストを自己無効化しますか?unlockedFieldsプロパティを使用して、これらのフィールドをcsrfチェックから除外できます。
CSRFチェックを完全に無効にすることもできます。これには明らかなセキュリティ上の影響がありますが、コンポーネントの操作に苦労している場合は、現在直面している問題を回避する簡単な方法です。
メカニズムを確認するために、コードを掘り下げて、FormHelperハッシュがどのように作成されるかと、SecurityComponent検証がハッシュをチェックする方法を確認しました。舞台裏で何が起こっているかを正確に確認する方法は次のとおりです。
FormHelperへの入力を確認します。 CORE / Cake / View / Helper/FormHelper.phpを開きます。secure()関数で、$ files = Security :: hash行の周りにいくつかのpr行を追加して、トークンがどのように構築されるかを確認します。
pr($fields);//hashed into computed token on next line
$fields = Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt'), 'sha1');
pr($unlocked); //hashed into computed token
pr(Configure::read('Security.salt')); //hashed into computed token
pr($fields); //computed token passed via hidden token field in form
フォームがどのように処理される かを確認する次に、送信されたフォームがどのように処理され、渡されたトークンと比較されるかを確認します。CORE/ Cake / Controller / Component/SecurityComponent.phpを開きます。最後に_validatePost()ルーチンにいくつかのpr行を挿入します。
pr($fieldList); //hashed into computed token
pr($unlocked); //hashed into computed token
pr(Configure::read('Security.salt')); //hashed into computed token
pr($token); //passed token from FormHelper
pr($check); //computed token
うまくいけば、これは、フィールドのロック/ロック解除または欠落に問題がある他の誰かがあなたのケーキの中で何が起こっているのかをすばやく理解するのに役立ちます。
また、 SessionToken
によって生成されたbuケーキと取得されたbuケーキを完全に一致させる必要があることも忘れないでください。FormHelper
ドキュメントにあるように、入力を動的に生成するとき、またはajax呼び出しを行うときに、不一致が発生する可能性があります。フォームをシリアル化して、ajax経由で送信することを忘れないでください。
を使用して生成されていない入力タグを生成したFormHelper
場合は、それらのロックを解除する必要があります。たとえばあなたのbeforeFilter()
:
$this->Security->unlockedFields =
array('MyModel.some_field1','MyModel.some_field2')
ここでfield1
、およびfield2
は「手動で」、つまりヘルパーを使用せずに生成されたフィールドです。
質問に答えるには:「詳細なエラーの説明を取得する方法はありますか?」
まず、SecurityComponentに関しては、コントローラーにさらに価値のあるデバッグを追加することです。これを行う1つの方法は次のとおりです。
public function beforeFilter() {
parent::beforeFilter();
//your beforeFilter code
//Enable CSRF and other protections
$this->Security->csrfExpires = '+1 hour';
$this->Security->csrfUseOnce = true;
$this->Security->blackHoleCallback = 'blackhole';
}
public function blackhole($errorType) {
$errorMap['auth'] = 'form validation error, or a controller/action mismatch error.';
$errorMap['csrf'] = 'CSRF error.';
$errorMap['get'] = 'HTTP method restriction failure.';
$errorMap['post'] = $errorMap['get'];
$errorMap['put'] = $errorMap['get'];
$errorMap['delete'] = $errorMap['get'];
$errorMap['secure'] = 'SSL method restriction failure.';
$errorMap['myMoreValuableErrorType'] = 'My custom and very ' .
'specific reason for the error type.';
CakeLog::notice("Request to the '{$this->request->params['action']}' " .
"endpoint was blackholed by SecurityComponent due to a {$errorMap[$errorType]}");
}
AD7sixが述べたように、を見てくださいCORE/Cake/Controller/Component/SecurityComponent.php
。具体的にはSecurityComponent::startup()
。そのメソッドでは、SecurityComponent::blackhole()
メソッドが数回実行されていることに気付くでしょう。基準がセキュリティチェックに失敗し、次のようになるたびに実行されます。
return $this->blackHole($controller, 'auth');
この場合、「auth」は失敗したセキュリティチェックのタイプを表します。'auth'文字列をカスタマイズして、より価値のあるものにすることができます。たとえば、「auth」の代わりに「myMoreValuableErrorType」を使用して、それをより意味のあるものにマップします。
したがって$this->blackHole($controller, 'auth')
、セキュリティチェックが失敗したときに実行する代わりに$this->blackHole($controller, 'myMoreValuableErrorType')
、上記のコードを使用して実行し、失敗した理由の特定の理由に「myMoreValuableErrorType」をマップします。