防護形式的篡改是由安全組件提供的基本功能之一。只要啓用,它將把所有POST視爲表單提交。
定期手動編碼的HTML表單在啓用安全組件時不起作用,因此JQuery生成的POST也不會生效。當然,您可以使用$this->Security->validatePost = false;
或$this->Security->csrfCheck = false;
,但是這時您將失去安全組件提供的保護。
爲了保持安全組件正常運行,您需要使用CakePHP Form Helper來創建您要通過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的序列化這種形式的物質使之能與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將成功。
重要:由於該表單輔助的令牌只能與安全組件中使用一次的事實,這個解決方案,如果你只打算POST每頁代一次纔有效。如果您需要能夠多次發佈相同的形式重新加載頁面之間,那麼你就需要做到以下幾點,當你在你的控制器的開頭添加安全組件:
public $components = array(
'Security' => array(
'csrfUseOnce' => false
)
);
...這將允許令牌用於多個請求。這不是作爲安全,但您可以將其與csrfExpires
結合使用,以便令牌最終過期。這全部記錄在CSRF configuration section of the Cake book中。
我正在調查這個,我很確定它的安全組件阻止我在這裏: http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html – kSeudo
好吧如果我禁用這個跨站點安全:$ this-> Security-> csrfCheck = false; 它的工作.....但顯然這是不是要走的路:) 任何想法? – kSeudo
你可以在/ usermgmt/users/editUser中發佈代碼 – Leo