2010-10-07 53 views
4

所有,試圖瞭解郵政/重定向/獲取設計模式(用PHP來實現)

對不起提前 - 我不是在設計模式PHP專家或知識淵博,所以這個問題可能有點基本...

無論如何,我正在開發一個需要登錄的web應用程序。

我的計劃是有這樣的事情:

的index.php:這個頁面將包含一個簡單的表單,允許用戶輸入用戶名和密碼。表單將POST輸入到...

login.php:此頁面將接收來自index.php的輸入,並根據數據庫檢查這些憑據。如果有任何的輸入被丟失,或者憑證檢查失敗,PHP腳本將REDIRECT用戶回到index.php的使用:

header('Location: http://www.mydomain.com/index.php'); 

如果憑證是有效的,那麼login.php中創建一個會話以建立用戶的身份驗證狀態:

session_start(); 
$_SESSION['authenticated'] = true; 

然後,它確定用戶擁有哪種訪問類型。如果他有「等級1」的訪問,該腳本將用戶重定向到使用level1.php:

header('Location: http://www.mydomain.com/level1.php'); 

如果用戶在「2級」的訪問,該腳本將用戶重定向到使用level2.php:

header('Location: http://www.mydomain.com/level2.php'); 

最後,當達到level1.php或level2.php時,他們所做的第一件事就是檢查會話。如果用戶沒有通過驗證,重定向他回到index.php文件:

session_start(); 
if (!isset($_SESSION['authenticated']) { 
    header('Location: http://www.mydomain.com/index.php'); 
} else { 
    // proceed to display the page 
} 

有了這個檢查在level1.php和level2.php將阻止用戶直接訪問該頁面,無需登錄

我的第一個問題是:這個簡單的邏輯第一次失敗 - 當達到level1.php時,「isset($ _ SESSION ['authenticated']」總是返回false,所以用戶總是重定向回index.php如果他第二次輸入完全相同的憑證,則該過程按原樣進行。

總之,由於我不明白的原因,似乎login.php設置的會話沒有被level1.php找到 - 我假定是因爲重定向。換句話說,對level1.php的檢查似乎是失敗的,直到/除非往客戶端的瀏覽器進行往返。

因爲每個需要登錄的站點都已經解決了這個問題,所以這不應該是一個新的挑戰,它們應該是一個非常成熟的模式。我應該如何處理它?

一個相關的問題......我見過類似的問題在這裏問過,大多數答案通常涉及一個解決方案,其中頁面張貼回自己。這似乎有點奇怪 - 理想情況下,我希望每個PHP頁面執行特定的工作:

  • 索引。PHP - 顯示一個表單來捕捉 憑據,然後把它們發佈到 的login.php
  • 的login.php - 評估用戶的 憑據,然後將它們引導到適當的 頁面
  • level1.php & level2.php - 顯示 適當的內容

這是一個有缺陷的設置?如果是這樣,什麼是更好的設置?

而且通常 - 如果一個頁面建立會話,然後將用戶重定向到另一個頁面 - 有什麼方法可以讓第二個頁面讀取會話?

有維基百科上有很大頁關於郵政/重定向/獲取:

http://en.wikipedia.org/wiki/Post/Redirect/Get

但它是一個小概念,我 - 我想看到它與特定網頁的引用解釋說:

例如「頁面A」上的表單將數據POST到「頁面B」,「頁面B」將用戶重定向到「頁面C」等等......

而且,我不明白它是如何與會話實現的,if會話在使用重定向時無法識別。

非常感謝您的任何建議和見解。


[更新]

感謝馬特·鮑爾的評論,我已經細化了問題:

login.php中被設置會話和用戶重定向到下一個屏幕:

session_start(); 
$_SESSION['authenticated'] = true; 
header('Location: http://www.mydomain.com/level1.php'); 

但是,當level1.php檢查該會話時,「已驗證」爲NOT SET

session_start(); 
echo (isset($_SESSION['authenticated']); // returns false 

但是,如果我改變的login.php,這樣的標題重定向到一個相對網址,而不是絕對的:

session_start(); 
$_SESSION['authenticated'] = true; 
header('Location: level1.php'); 

然後,level1.php就像我期望:

session_start(); 
echo (isset($_SESSION['authenticated']); // now returns true 

我不明白爲什麼相對URL有所作爲,但確實如此。所以,至少我的直接問題已經解決了。

非常感謝大家的評論!


乾杯, 馬特Stuehler

+5

在有關會議上,問題在黑暗中拍攝:你怎麼叫'在session_start();在level1.php' ?另一件事:出於安全原因,你不僅應該檢查會話在level1 ... x.php中是否有效,而且如果用戶的級別足夠。否則,Level1用戶可以登錄,然後手動調用level2.php。 – Select0r 2010-10-07 13:39:51

+1

你應該使用像Firebug + FireCookie這樣的工具來檢查當login.php發送它的頭文件時PHPSESSID cookie是否真的被設置,並且之後它們也存在。 – SirDarius 2010-10-07 13:40:42

+2

我認爲你需要開始你的會話,然後在用戶登錄後重新導向 – 2010-10-07 13:46:17

回答

1

發佈重定向如果用戶在提交表單後刷新了他們已重定向到的頁面,則可以開始播放以停止用戶重新發送POST數據。當你想實現一個PRG,你應該HTTP標頭代碼設置爲303這樣的:

header('Location: level1.php', 303); 
+0

應該檢查POST操作是否首先發生。我更喜歡這個代碼,因爲它更完整:http://stackoverflow.com/a/4142969/631764 – 2012-12-23 03:44:54

0

如果憑證是有效的,然後登錄。PHP創建一個會話建立用戶的認證狀態:

我在黑暗中拍攝的很好,但我的印象中,你可以輸出東西login.php中的設置會話之前。將session_start作爲第一條指令放入每個文件中。