6

アクションにajax投稿を使用しようとしています。GETリクエストは正常に機能しますが、POSTしようとすると、firebugに「400Bad Request」が表示され、ビューは「ブラックホール」応答を返します。

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');
            }
        });

これはCakeのセキュリティ設定によるものですか、それともここで何が欠けているのですか?

4

4 に答える 4

18

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

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

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

<?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 でシリアライズして、ajax POST で送信できるようにするだけです。

    $('#testform').submit(function(event) {
        $.ajax({
            type: 'POST',
            url: "/your/url",
            data: $('#testform').serialize(),
            success: function(data){ 
                alert('Wow this actually worked');
            },
            error:function() {
                alert('This will never work');
            }
        });
        event.preventDefault(); // Stops form being submitted in traditional way
    });

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

重要:フォーム ヘルパーのトークンはセキュリティ コンポーネントで 1 回しか使用できないため、このソリューションは、ページ生成ごとに POST を 1 回だけ行う場合にのみ機能します。ページのリロードの間に同じフォームを数回投稿できるようにする必要がある場合は、コントローラーの先頭にセキュリティ コンポーネントを追加するときに次のことを行う必要があります。

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

...これにより、トークンを複数のリクエストに使用できるようになります。それほど安全ではありませんcsrfExpires、トークンが最終的に期限切れになるように組み合わせることができます。これはすべてCake book の CSRF 設定セクションに記載されています。

于 2012-06-27T08:34:49.107 に答える
4

参考までに、CakePHP 2.3 以降には、この目的のためだけに、コントローラーまたは AppController の beforeFilter で使用される unlockedActions が含まれています。

$this->Security->unlockedActions = array('ajaxAction');

から: http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#disabling-security-component-for-specific-actions

于 2013-04-02T09:51:37.630 に答える
0

関数editUserを次の場所に配置していることを確認してください。

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

UsersControllerの内部、

よろしく

于 2012-05-17T00:04:37.907 に答える
0

ジョセフの答えには、私にとって1つの詳細が欠けていました。私のフォームと ajax 呼び出しは index.ctp にあり、/controller/edit.ctp を呼び出していたので、私の $this->Form->create 呼び出しには 'action'=>'/controller/edit' を追加する必要がありました。

于 2015-02-25T01:35:47.770 に答える