2011-08-17 200 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设置为仅显示登录表单的操作。