2009-08-07 67 views
6

我有以下代碼用於開始會話並存儲用戶名/密碼數據,如果沒有提交任何內容或者沒有會話數據存儲,則重定向到失敗頁面。php會話在登錄表上對用戶進行身份驗證

session_start(); 
if(isset($_POST['username']) || isset($_POST['password'])) { 
    $username = $_POST['username']; 
    $password = $_POST['password']; 
    $_SESSION['username'] = $username; 
    $_SESSION['password'] = $password; 
} 

if(isset($_SESSION['username']) || isset($_SESSION['password'])){ 
    $navbar = "1"; 
    $logindisplay = "0"; 
    $username = $_SESSION['username']; 
    $password = $_SESSION['password']; 
} else { 
    header('Location:http://website.com/fail.php'); 
} 

$authed = auth($username, $password); 
if($authed == "0"){ 
    header('Location:http://website.com/fail.php'); 
} 

它不工作的方式,它應該和重定向我失敗,即使我提交我的信息並將其存儲在會話中。難道我做錯了什麼?

注意在添加會話代碼之前,authed函數正常工作。

+0

您是否啓用了cookies? – random 2009-08-07 06:16:05

回答

17

怎麼樣使用這個設置會話

session_start(); 
if(isset($_POST['username']) && isset($_POST['password'])) 
{ 
    if(auth($_POST['username'], $_POST['password'])) 
    { 
     // auth okay, setup session 
     $_SESSION['user'] = $_POST['username']; 
     // redirect to required page 
     header("Location: index.php"); 
    } else { 
     // didn't auth go back to loginform 
     header("Location: loginform.html"); 
    } 
} else { 
    // username and password not given so go back to login 
    header("Location: loginform.html"); 
} 

,並在每個「安全」頁面使用的頂部驗證碼:

session_start(); 
session_regenerate_id(); 
if(!isset($_SESSION['user']))  // if there is no valid session 
{ 
    header("Location: loginform.html"); 
} 

這樣下去的代碼極少量的頂部而不是在每個頁面頂部運行完整的身份驗證。要註銷會話:

session_start(); 
unset($_SESSION['user']); 
session_destroy(); 
header("Location: loginform.html"); 
+0

'session_regenerate_id'在這裏做什麼? – Richard 2015-08-25 14:55:54

+0

@Richard可能試圖逃避會話修復 – Marki 2016-03-26 12:27:09

+0

如果未使用session_regerate_id,則會話ID將保持不變,直到瀏覽器關閉或會話過期,即使頁面已刷新。攻擊者可以通過訪問該站點獲得自己的會話ID,將其作爲?SID = SESSIONID發送給受害者,受害者使用鏈接而不知道和登錄,這意味着此會話ID現在有權訪問該站點,因爲它是攻擊者的會話ID,攻擊者可以作爲受害者訪問站點,直到會話ID過期(需要一些時間) – Liyanage 2017-10-05 11:18:37

9

首先,不要在會話中存儲密碼。這是一個壞事。其次,不要將用戶名存儲在會話中,直到之後已經通過身份驗證。

嘗試以下操作:

<?php 

session_start(); 

if (isset($_POST['username']) && isset($_POST['password'])) { 
    $username = $_POST['username']; 
    $password = $_POST['password']; 
    $authed = auth($username, $password); 

    if (! $authed) { 
     header('Location: http://website.com/fail.php'); 
    } else { 
     $_SESSION['username'] = $username; 
    } 
} 

if (isset($_SESSION['username'])) { 
    $navbar = 1; 
    $logindisplay = 0; 
} else { 
    header ('Location: http://website.com/fail.php'); 
} 
+0

那麼如果你必須將用戶名/密碼傳遞給第三方API,那麼我猜你不想逃避它。我會把它留給他們。 – hobodave 2009-08-07 06:27:38

2

只是一些隨機點,即使他們實際上可能沒有涉及到這個問題:

  • 不要在明文密碼存儲在會話。只評估密碼是否正常,然後在會話中存儲loggedIn = true或類似內容。

  • 檢查密碼的用戶名是$_POSTed,不||(或)。

  • 請勿在$password$_SESSION['password']之間來回傳遞密碼和用戶名。決定一個地方保存數據並保留在那裏。

  • 您是否檢查過會議中是否可以存儲任何內容?餅乾好吧等...?

爲了大大簡化您的代碼,這不是你需要做的嗎?

if (isset($_POST['username'] && isset($_POST['password'])) { 
    if (auth($_POST['username'], $_POST['password'])) { 
     $_SESSION['user'] = /* userid or name or token or something */; 
     header(/* to next page */); 
    } else { 
     // display "User credentials incorrect", stay on login form 
    } 
} else { 
    // optionally: display "please fill out all fields" 
} 
+0

密碼僅用於通過站點訪問第三方API。 auth基本上使用第三方站點進行身份驗證,因此我必須將密碼傳遞給api(以純文本格式)。任何替代建議將不勝感激雖然,即時通訊顯然是新的。 – mrpatg 2009-08-07 06:26:01

+0

好的,這取決於你的具體情況,除非你澄清那些很難提出任何建議。不過,你是否必須將它存儲在會話中?我猜''authed()'第三方檢查?你必須不止一次這樣做? – deceze 2009-08-07 06:33:05

+0

^^應該是*'auth()'*。 – deceze 2009-08-07 06:34:54

0

解決我的具體問題上面

session_start(); 
if(isset($_POST['username']) || isset($_POST['password'])){ 
$username = $_POST['username']; 
$password = $_POST['password']; 
$_SESSION['username'] = $username; 
$_SESSION['password'] = $password; 
} 

if(isset($_SESSION['username']) || isset($_SESSION['password'])){ 
$navbar = "1"; 
$logindisplay = "0"; 
$username = $_SESSION['username']; 
$password = $_SESSION['password']; 
$authed = auth($username, $password); 
if($authed == "0"){ 
header('Location:http://website.com/fail.php'); 
} 
} else { 
header('Location:http://website.com/fail.php'); 
} 
+0

恕我直言,在驗證之前應設置'username'和'password'證書。 – 2015-08-07 13:49:22

1

這裏有一些其他的事情,這可能會或可能不會幫助你,順便說一句:

  • 你有error_reporting上 ? (see also
  • 您有display_errors嗎?
  • session_start你在頁面上做的第一件事是什麼?必須有沒有之前輸出
  • 是在客戶端上創建的cookie?
  • header位置表示瀏覽器必須轉到另一個頁面;它不會停止執行PHP腳本。你可能想要(幾乎總是)在它後面添加「退出」。
+0

會議第一個好點,不知道,謝謝 – mrpatg 2009-08-07 06:41:21

+0

不客氣:-)其實,它比這更復雜一點:session_start發送cookies; cookies作爲HTTP標頭髮送;只有在沒有輸出發送時才能發送HTTP頭信息;所以,應該在任何輸出生成之前使用session_start。 (有一個例外,如果你正在使用output_buffering;但你不能依靠它) – 2009-08-07 06:50:29

+0

這真的是很好的信息,實際上,永遠不會想到。所以會話基本上是服務器管理的cookie? – mrpatg 2009-08-07 07:01:27

1

標題不是函數調用。他們在HTTP標頭中加入了一個指令,而最後一個要執行的指令將被處理。因此,讓我們說,如果你有這樣的事情

if ($bAuthed) 
{ 
    header("location: login.php"); 
} 

// error case 
header("location: error-login.php"); 

你總是會被重定向到錯誤-login.php中無論發生什麼事情。頭文件不是函數調用!

0

不要使用第二if聲明else部分。

session_start(); 

if(isset($_POST['username']) || isset($_POST['password'])) { 

    $username = $_POST['username']; 

    $password = $_POST['password']; 

    $_SESSION['username'] = $username; 

    $_SESSION['password'] = $password; 

} 

if(isset($_SESSION['username']) || isset($_SESSION['password'])){ 

    $navbar = "1"; 

    $logindisplay = "0"; 

    $username = $_SESSION['username']; 

    $password = $_SESSION['password']; 

} 

$authed = auth($username, $password); 

if($authed == "0"){ 

    header('Location:http://website.com/fail.php'); 

}