2011-06-13 50 views
4

我使用Zend-Form在我的項目中生成我的表單。Zend表單 - 一個頁面中的多個表單和(CSRF)令牌驗證

第一:如何處理同一頁面上的多個表單,並且只發布提交的表單?

第二:當我在同一頁上有兩個表單時,令牌只會驗證HTML中最頂層的呈現表單。第二種形式獲得「令牌不匹配」錯誤,從而使表單無法發佈。你如何給每個表單一個與其他表單不衝突的唯一標記?

真誠的,爲什麼

+0

http://stackoverflow.com/questions/1170857/zend-form-multiple-forms-on-same-page – 2011-06-13 11:09:52

+0

解決第一個問題。第二個問題呢? – why 2011-06-13 11:13:27

+0

你爲每個表單呈現了一個csrf字段嗎? – martynthewolf 2011-06-13 12:02:44

回答

6

當我有在同一頁上兩種形式的代幣只驗證HTML中最頂層的呈現形式。第二種形式獲得「令牌不匹配」錯誤,從而使表單無法發佈。你如何給每個表單一個與其他表單不衝突的唯一標記?

令牌上的多個形式是不可能的當前implementation(見initCsrfValidator)。

我建議您生成自己的令牌,將其存儲在會話中(使用表單ID)並自行驗證。

+0

我以爲你可以使用散列做多個表單,只要他們有不同的會話對象來存儲它們的散列呢?看起來如果你給它們不同的名字會發生什麼,因爲會話名稱空間使用對象名稱。 – 2011-06-24 12:21:58

0

我遇到的

同樣的情況時,我有同一個頁面上有兩種形式的代幣只驗證 在HTML最頂端的呈現形式。第二種形式獲得 「令牌不匹配」錯誤,從而使表單無法發佈。 如何給每個表單一個與其他 不衝突的唯一標記?

一個可能的解決方案是隻有一個單獨的表單用於令牌生成和驗證。然後在HTML中,每個表單都有自己的標記元素,但具有相同的值。如果您提交了一個表單,然後使用您用於生成該表單的表單來驗證此標記元素。如果您使用的是混合使用ajax表單和傳統的POST表單,則可以在響應中發送新令牌並將其分配給每個令牌元素。

//Finally set the response token 
    $form->getElement('token')->render(); //Need to call render in order to regenerate the token 
    $response['token'] = $form->getElement('token')->getValue(); 
    $this->_helper->json($response); 

而且在jQuery的你可以有像$(「._令牌」)。VAL(response.token)

其實,這是很容易的,比擁有一個Zend_Form_Element_Hash添加到每個更棒形成。

3

我在使用Zend_Form_Element_Hash試圖在同一頁上使用兩種表單時發現此問題。有兩種方法可以完成此操作,它們都是mentioned in the documentation

散列元素的名稱應該是唯一的。我們推薦使用元素的鹽選項 - 兩個具有相同名稱和不同鹽的哈希不會相互碰撞

因此...

  1. 每個Hash元素
  2. 使用
0

我其實只是固定的我在那裏產生相同形式的多個副本類似的問題對每個Hash元素的獨特的鹽值使用唯一名稱csrf保護。發生的事情是隻有最後創建的表單才具有正確的csrf標記。

處理此問題的草率方法是更改​​Zend庫(位於Zend_Form_Element_Hash文件中)中的跳躍,以便令牌在1次刷新或頁面加載後不會過期。這是解決問題的一種非常簡單的方法,但只有在知道頁面加載的次數時纔有效。這是蟒蛇解決方案

正確的方法來做到這一點是一旦頁面加載做一個Ajax調用來獲得一個新的刷新令牌。然後使用你的JavaScript庫(jquery可能是最簡單的),並找到令牌的所有實例,並用新的代替全部。

所以在代碼方面,它應該是這樣的: 控制器:

$形式 - >散列> initCsrfToken(); $ this-> view-> hash = $ form-> hash-> getValue(); $ this-> hash-> getValue();

在你的js文件(如果你使用jQuery)

$ .replaceWith(哈希值。)( 'HiddenHtmlPart1'=散 'HiddenHtmlPart2'); 重要的部分是讓選擇器選擇所有隱藏的元素。然後你只需要替換隱藏元素的內部。同樣的想法適用於其他js庫,儘管它涉及不同的方法。