2011-08-17 132 views
9

我有一個採取由sfGuard保護的POST數據的操作。這意味着如果用戶沒有登錄,POST數據將被髮送到登錄表單中。通常,這不是問題,用戶會繼續登錄,並且必須重新提交數據。發送POST請求到安全操作

不幸的是,登錄表單似乎在使用POST數據,就好像它是使用表單本身一起提交的。這意味着它抱怨所需的用戶名和密碼字段丟失,並且它抱怨缺少CSRF令牌。提交表單後,最後一個問題不會消失,意味着用戶無法登錄。

如果用戶未登錄,則不應該顯示該用戶,但用戶可能仍然可以用仍然打開的表單登出。所以我要求保持界面的水密性和無錯誤。

這是sfGuard的缺點,可以避免嗎,還是我做錯了什麼?

爲了澄清,路線是這樣的:

add_subgroup: 
    url:  /group/:id/add 
    class: sfPropelRoute 
    options: 
    model: Group 
    type: object 
    param: { module: subgroups, action: create } 
    requirements: 
    group_id: \d+ 
    sf_method: [post] 

用於提交請求的格式如下:

<form action="<?php echo url_for('add_subgroup', $group) ?>" method="post"> 
    <input type="hidden" name="group_id" value="<?php echo $group->getId() ?>" /> 
    <input type="text" name="subgroup_id" /> 
    <input type="submit" class="button" value="Add" /> 
</form> 
+0

你可以更具體的是你想做一個登錄表單還是什麼? – Henry

+0

我正在嘗試調用一個安全操作。如果用戶沒有登錄,它會轉到現有的登錄表單。由於此操作需要POST數據,因此此POST數據會干擾表單。你能更具體地說我應該更具體一些嗎? – Druckles

+0

如果用戶未登錄,您將如何處理?如果您發出標題重定向,則應該清除POST數據。如果您將其包含在內,則POST數據將存在。 –

回答

6

這是sfGuard的一個缺點,因爲登錄操作會檢查POST請求,如果綁定了表單。

從BasesfGuardActions.class.php代碼:

if ($request->isMethod('post')) 
{ 
    $this->form->bind($request->getParameter('signin')); 

我個人不symfony的動作之間轉發的大風扇,並且就像在這種情況下,我認爲這是比較合適的重定向比向前。這也解決了你的問題,因爲這會導致一個新的GET請求。您可以通過擴展sfGuardBasicSecurityFilter來完成此行爲。

class mySecurityFilter extends sfGuardBasicSecurityFilter 
{ 

    protected function forwardToLoginAction() 
    { 
    $context = $this->getContext(); 
    // If you want to redirect back to the original URI (note: original POST data will be lost) 
    $context->getUser()->setReferer($context->getRequest()->getUri()); 
    $url = sfConfig::get('sf_login_module') . '/' . sfConfig::get('sf_login_action'); 
    $context->getController()->redirect($url); 
    throw new sfStopException(); 
    } 

} 

現在,在應用程序/ MyApp的/配置/ filters.yml

security: 
    class: mySecurityFilter 
0

這可能是因爲你把代碼的身份驗證登錄數據在同一行動中(通過檢查請求是否發佈)。

但是,您可以將一個動作分爲兩個動作。一個用於顯示登錄表單,另一個用於驗證用戶的登錄數據。並將您的secure_action設置爲僅顯示登錄表單的操作。