2016-07-27 46 views
2

我在PHP 5.5.28上使用Symfony v3.0.6並啓用了OPcache。 網站管理員的安全性由FOSUserBundle管理。Symfony3來自同一個域的iframe的AJAX請求不會保存會話屬性

網站用戶訪問他們顯示非Symfony的形式在iframe從一個Ajax請求,簡單的Symfony行動同一個域的頁面:

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; 
} 

正如你可以看到我叫我的定製服務安全管理器,其中i屬性添加到會話:

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調試工具欄後,在之前的請求中未顯示任何屬性設置的跡象。 我也試過使用Cookies,但沒有成功。相同的模式仍然存在。

+0

我想知道是否需要在其他控制器頁面調用getSession()方法,如下所示:'$ session = $ request-> getSession();'。我知道當我使用會話變量時,我必須在所有控制器上執行此操作。這可能不是解決方案,但你可以檢查。我不再使用會話變量,而是現在使用路由參數,因爲需要的編碼少得多,而且看起來更乾淨。 –

+0

每次我需要使用'getSession'時都會調用它。它看起來像問題本身在於iframe和主頁有單獨的會話,我沒有找到一種方法來分享他們之間的東西。 –

回答

0

問題解決了,簡短的課程 - 不使用iframe或框架。永遠。

和主頁面有單獨的PHP會話(檢查會話ID)。所以車過程看起來像這樣:

  1. AJAX請求從
  2. Symfony的行動更新屬性派往會議
  3. 響應200回來和JavaScript重新加載整個頁面(window.reload())。
  4. 在頁面加載主頁會話檢查令牌,顯然沒有那裏,所以登錄表單顯示。

重要說明!

一些較舊的瀏覽器或新瀏覽器,但安全性/隱私設置較不嚴格的主頁和可能使用相同的會話。

這是爲什麼花了這麼長時間才找到這個錯誤的主要原因。它看起來像代碼行爲不一致。

在放棄使用>iframe>之後,代碼就像魅力一樣工作。

謝謝大家的意見。希望這將爲其他程序員在未來節省一些時間。

0

我正在使用Symfony 3.1並能夠通過ajax保存會話信息。

也許,您應該注入@session作爲服務參數,而不是作爲參數傳遞給服務中的方法。

+0

我會試試這個解決方案。到處都有記錄器,所以看起來會話在驗證操作中用新參數更新,但在頁面重新加載新參數時不再存在。 –

+0

沒有任何變化。據我可以看到,我的主頁和iframe中有兩個單獨的會話,其中有形式。兩者都在同一個域中。 –

相關問題