来自同一域的iframe的Symfony3 AJAX请求不保存Session属性

时间:2016-07-27 08:02:22

标签: php ajax session symfony

我在PHP 5.5.28上使用Symfony v3.0.6并启用了OPcache。 站点管理员的安全性由FOSUserBundle管理。

网站用户访问一个页面,在该页面中,来自同一域的iframe中显示非Symfony表单,从而对简单的Symfony操作发出AJAX请求:

public function validateAction(MailingList $mailingList, Request $request)
{
  $email = $request->get('email');
  $code = $request->get('code');
  if ($mailingList->getCode() == $code) {
    $response = new Response('', 200);
    $securityManager = $this->get('security_manager');
    $securityManager->grantAccess($request->getSession(), $mailingList, $email);
    $response->headers->set('Access-Control-Allow-Origin', '*');
    return $response;
  }
  $responseFailed = new Response('N2', 401);
  $responseFailed->headers->set('Access-Control-Allow-Origin', '*');
  return $responseFailed;
}

正如您所见,我调用我的自定义服务SecurityManager,其中我向Session添加了一个属性:

public function grantAccess(Session $session, MailingList $mailingList, $email) {
  $session->set('page_'.$mailingList->getId(), 
    json_encode(array(
      0 => hash('sha256', $email.$mailingList->getCode()),
      1 => $email
    ))
  );
}

AJAX调用成功,整个页面重新加载window.reload()

重新加载Symfony调试工具栏后,在上一个Request中没有显示任何属性设置的迹象。 我也试过使用Cookies,但没有成功。同样的模式仍然存在。

2 个答案:

答案 0 :(得分:0)

我正在使用Symfony 3.1并能够通过ajax保存会话信息。

可能是,您应该将@session作为服务参数注入,而不是作为参数传递给服务中的方法。

答案 1 :(得分:0)

问题解决了,短课程 - 不使用iframe或框架。如初。

<iframe>,主页面有单独的PHP会话(检查会话ID)。因此,错误的过程看起来像:

  1. AJAX请求是从<iframe>
  2. 发送的
  3. Symfony操作更新<iframe>会话
  4. 中的属性
  5. 响应200返回,JavaScript重新加载整个页面(window.reload())。
  6. 在页面加载主页面会话检查令牌,显然没有,所以登录表单会显示。
  7. 重要提示!

    某些较旧的浏览器或新浏览器,但安全/隐私设置不太严格,可能会对主页和<iframe>使用相同的会话。

    这就是为什么花了这么长时间来捕捉这个错误的主要原因。看起来代码行为不一致。

    在放弃使用>iframe>后,代码就像魅力一样。

    感谢大家的想法。希望这能为将来的其他程序员节省一些时间。