我有一个关于CSRF安全性和登录表单的问题。表格如下:
在主布局中,视图助手会创建一个登录表单,稍后还会在用户通过身份验证后显示用户特定的菜单。
// User menu viewhelper
public function authentication()
{
// Check if user is authenticated or not
$auth = Zend_Auth::getInstance();
if(!$auth->hasIdentity())
{
$form = new Application_Form_Login();
$form->setAction($this->_view->url(array('action' => 'login'), 'ucp', true));
return $form;
}
else
{
// return user specific menu
}
}
表单发布到包含所有用户控制面板逻辑的UcpController,例如登录/注销和显示用户特定信息。
// loginAction in UcpController
public function loginAction()
{
if(Zend_Auth::getInstance()->hasIdentity())
{
$this->_redirect('/');
return;
}
$request = $this->getRequest();
$form = new Application_Form_Login();
if($request->isPost())
{
if($form->isValid($post = $request->getPost()))
{
// Do authentication stuff here.
}
}
$this->view->form = $form;
}
可悲的是,这种方式CSRF令牌无法匹配,我对如何解决这个问题毫无头绪。我在这里错过了什么吗?我应该一起删除CSRF验证吗?
// The CSRF protection element as added to the login form
$this->addElement('hash', 'csrf',
array(
'ignore' => true
)
);
在此先感谢,非常感谢您的帮助:)
答案 0 :(得分:0)
您的代码似乎正确,我认为问题可能在其他地方。要调试此问题,请执行以下操作:
使用firebug检查生成的Application_Form_Login
,特别是CSRF令牌,然后在发布数据时尝试Zend_Debug::dump
您的loginAction中的$_SESSION
和$_POST
数组比较结果。您应该在发布的数据和会话数据之间找到匹配项。
您应该搜索已发送的post变量和名为Zend_Form_Element_Hash_salt_<name-of-your-element>
的会话变量之间的匹配项,如果值匹配,则错误发生在其他地方,您应该转储$form->getMessages()
以找到它。
正如zerkms在评论中指出的那样,我之前的判决是错误的。我查看了implementation,我发现ZF中的CSRF令牌在300秒内改变了一次,这个超时令牌到期应该不是您的问题。
答案 1 :(得分:0)
问题解决了!我遇到了遇到同样问题的人。原因很奇怪:http://tinyurl.com/3fkg8bk(ZF论坛)。
当它转向我时,我的favicon返回了一个HTTP 500代码,因为该文件不存在。这显然会触发生成新的CSRF。我没有丝毫的线索为什么,但它解决了我的问题,创建一个图标并将其上传到webroot。
感谢至少和我一起思考!