簡體   English   中英

Zend Form - 一頁中有多個 forms 和(CSRF)令牌驗證

[英]Zend Form - multiple forms in one page and (CSRF) token validations

我使用 Zend-Form 在我的項目中生成我的 forms。

第一:如何處理同一頁面上多個forms,只post提交的表單?

第二:當我在同一頁面上有兩個 forms 時,令牌將僅驗證 HTML 中最頂層呈現的表單。 第二個表單出現“令牌不匹配”錯誤,從而使表單無法發布。 你如何給每個表單一個不與其他表單沖突的唯一令牌?

真誠的,為什么

當我在同一頁面上有兩個 forms 時,令牌將僅驗證 HTML 中最頂部的呈現形式。 第二個表單出現“令牌不匹配”錯誤,從而使表單無法發布。 你如何給每個表單一個不與其他表單沖突的唯一令牌?

當前實現無法使用多個 forms 上的令牌(請參閱initCsrfValidator )。

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

我在嘗試使用Zend_Form_Element_Hash在同一頁面上有兩個 forms 時發現了這個問題。 有兩種方法可以做到這一點, 文檔中都提到了這兩種方法:

hash 元素的名稱應該是唯一的。 我們建議對元素使用 salt 選項 - 兩個具有相同名稱和不同鹽的哈希不會發生沖突

所以...

  1. 為每個Hash元素使用唯一名稱
  2. 為每個Hash元素使用唯一的鹽值

實際上,我剛剛修復了一個類似的問題,即我生成了具有 csrf 保護的相同表單的多個副本。 發生的事情是只有最后一個創建的表單具有正確的 csrf 令牌。

處理這個問題的草率方法是更改 Zend 庫中的躍點(在 Zend_Form_Element_Hash 文件中),以便令牌在 1 次刷新或頁面加載后不會過期。 這是解決問題的一種非常簡單的方法,但只有在您知道頁面將加載多少次時才有效。 這是創可貼解決方案

正確的方法是在頁面加載后執行 ajax 調用以獲取新的刷新令牌。 然后使用您的 javascript 庫(jquery 可能是最簡單的)並找到令牌的所有實例並將它們全部替換為新的。

所以就代碼而言,它看起來像這樣:Controller:

$form->hash->initCsrfToken();

$this->view->hash = $form->hash->getValue();

在您的 js 文件中(如果您使用的是 jquery)

$(.hash).replaceWith('HiddenHtmlPart1'.=hash.'HiddenHtmlPart2'); 重要的部分是選擇器到 select 的所有隱藏元素。 然后你只需要替換隱藏元素的內部。 相同的想法適用於其他 js 庫,盡管它會涉及不同的方法。

我遇到了同樣的情況

當我在同一頁面上有兩個 forms 時,令牌將僅驗證 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 中,您可以使用 $('._token').val(response.token)

事實上,這比必須向每個表單添加 Zend_Form_Element_Hash 非常簡單,甚至更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM