2012-05-16 22 views
5

私はアクションにajax投稿を使用する傾向があります。 GETリクエストはうまく動作しますが、POSTしようとすると「400 Bad Request」が火かき棒で表示され、「Black hole」応答が返されます。ここでCakePHP ajax投稿は400のバッドリクエストを返し続けます

は、jQueryのリクエストです:

  $.ajax({ 
      url:"/usermgmt/users/editUser", 
      type:"POST", 
      success:function(data) { 
       alert('Wow this actually worked'); 
       //ko.applyBindings(self); 

      }, 
      error:function() { 
       alert('This will never work'); 
      } 
     }); 

はケーキのセキュリティ設定のために、このですか私はここで何をしないのですか?

+0

私はこれを見て、セキュリティのコンポーネントがここで私を止めていると確信しています: http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html – kSeudo

+0

Okもし私がこれでクロスサイトセキュリティを無効にするなら、$ this-> Security-> csrfCheck = false; これは動作しますが、明らかにこれは行く方法ではありません:) アイデア? – kSeudo

+0

あなたは/ usermgmt/users/editUserにコードを投稿することができます – Leo

答えて

18

保護は、セキュリティコンポーネントによって提供される基本的な機能の一つです。有効になっている限り、すべてのPOSTをフォーム提出として扱います。

通常の手作業でコード化されたHTMLフォームは、セキュリティコンポーネントが有効な状態では動作しません。したがって、JQueryによって生成されたPOSTも有効になりません。もちろん、$this->Security->validatePost = false;または$this->Security->csrfCheck = false;を使用できますが、セキュリティコンポーネントが提供する保護が失われます。

セキュリティコンポーネントを正常に保ち、正常に動作させるには、CakePHPフォームヘルパーを使用して、ajax経由で投稿するフォームを作成する必要があります。このようdata[_Token][fields]data[_Token][unlocked]隠しフィールドは、そのキーを使用して生成されます:

<?php 
    echo $this->Form->create('Test',array('id'=>'testform')); 
    echo $this->Form->input('Something'); 
    echo $this->Form->submit(); 
    echo $this->Form->end(); 
?> 

これは、次のようなものが生成されます。

<form action="/your/url" id="testform" method="post" accept-charset="utf-8"> 
    <div style="display:none;"> 
     <input type="hidden" name="_method" value="POST"/> 
     <input type="hidden" name="data[_Token][key]" value="9704aa0281d8b5a2fcf628e9fe6f6c8410d8f07a" id="Token937294161"/> 
    </div> 
    <div class="input text"> 
     <input name="data[Test][Something]" class="required" type="text" id="TestSomething"/> 
    </div> 
    <div class="submit"> 
     <input type="submit" /> 
    </div> 
    <div style="display:none;"> 
     <input type="hidden" name="data[_Token][fields]" value="0c81fda1883cf8f8b8ab39eb15d355eabcfee7a9%3A" id="TokenFields817327064"/> 
     <input type="hidden" name="data[_Token][unlocked]" value="" id="TokenUnlocked281911782"/> 
    </div> 
</form> 

は、今ではそれができるように、jQueryのでは、このフォームをシリアル化の問題ですPOST:

送信ボタンを押すと、POSTが成功します。

重要:フォームヘルパーのトークンはセキュリティコンポーネントで一度しか使用できないため、このソリューションは、ページ生成ごとに1回だけPOSTする場合にのみ機能します。

public $components = array(
    'Security' => array(
     'csrfUseOnce' => false 
    ) 
); 

...この意志を:あなたはページをリロード間で同じフォームを何度も投稿できるようにする必要がある場合は、あなたのコントローラの先頭にセキュリティコンポーネントを追加するとき、あなたは次のことを行う必要がありますトークンを複数の要求に使用できるようにします。 として安全ではありませんが、csrfExpiresと組み合わせると、最終的にトークンが期限切れになることがあります。これはすべてCSRF configuration section of the Cake bookに記載されています。

+1

非常に有用な答え - ありがとう! – Dave

+2

JavaScriptに 'hidden'入力フィールドが変更された場合にもエラーが検出されるため、トークンはこれらのフィールドを追跡しているため、これに少し追加したいだけです。 validatePostを無効にしたくない場合は、フィールドを非表示からテキストタイプのフィールドに変更し、css(表示:なし)で非表示にします。これにより、JavaScriptが入力フィールドを変更してもフォームが正しく送信されます。 – TeckniX

+0

非常に良いと詳細な答えは、これはまったく同じ問題から私を助け、それは私がSecurityComponentだったことを理解するためにしばらく時間がかかりました。 +1、あなた! – Oldskool

0

メイクSHUREあなたが機能editUserを入れていますがUserControllerの内部

public function beforeFilter(){ 
    parent::beforeFilter() 
    $this->Auth->allow('editUser'); 
    } 

、フォームが改ざんに対する

よろしく

0

。私のフォームとajaxコールはindex.ctpにあり、/controller/edit.ctpを呼び出していましたので、$ this-> Form-> create callに 'action' => '/ controller/edit'が必要でした。

関連する問題