2013-04-22 38 views
1

我有一個類來登錄用戶,但是當我使用表單和錯誤憑證對其進行測試時,我仍然獲得'成功'。有人能指出我正確的方向嗎?爲什麼這個登錄表單不工作?

include('User.datatype.php'); 

$usher = new Authenticator; 
$usher->checkCreds(); 
$usher->ensureHasAccess(); 

Class Authenticator { 
    protected $user; 
    protected function getCreds() { 
     if (!isset($_POST['login'])) 
      throw new Exception("There was an error processing your request", 1); 
     else if ($_POST['username'] == '' || $_POST['password'] == '') 
      throw new Exception("You must enter a username and password", 1); 
     $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING); 
     $password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING); 
     $this->user = new User; 
     $this->user->username = $username; 
     $this->user->password = $password; 
    } 

    public function checkCreds() { 
     $this->getCreds(); 
     if (empty($this->user->username) || empty($this->user->password)) 
      throw new Exception("Error Processing Request", 1); 
     include('dbconnect.php'); // Normally I'd store the db connect script outside of webroot 
     $pdo = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_password); 
     $stmt = $pdo->prepare('SELECT * FROM Users WHERE username = :uname AND password = :pword'); 
     $stmt->bindParam(':uname', $this->user->username); 
     $stmt->bindParam(':pword', $this->user->password); 
     $stmt->execute(); 
     $status = $stmt->fetch(); 
     $this->user->status = $status; 
     print $status; 
     return $this->user->status; 
    } 

    protected function createSessionID() { 
     $seshID = mt_rand(99999, 1000000); 
     return $seshID; 
    } 

    protected function startSession() { 
     if (empty($this->user->status)) 
      throw new Exception("There was a problem connecting to the database", 1); 
     session_start(); 
     $_SESSION['username'] = $this->user->username; 
     $_SESSION['id'] = createSessionID(); 
     $secret = $_SESSION['id']; 
     header('Location:index.php?' . $secret); 
     return true; 
    } 

    protected function hasAccess() { 
     $this->startSession(); 
     if (!startSession()) 
      throw new Exception("You do not have access to this page.", 1); 
     return true; 
    } 

    public function ensureHasAccess() { 
     if(!$this->hasAccess()) 
      throw new Exception("You are not logged in."); 
     print 'Welcome, ' . $this->user->username; 
    } 
} 

HTML表單:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> 
    <head> 
    </head> 
    <body> 
     <form action="authenticator.php" method="post"> 
      <p>username: <input type="text" name="username" /></p> 
      <p>password: <input type="password" name="password" /></p> 
      <p><input type="submit" name="login" /></p> 
     </form> 
    </body> 
</html> 
+0

你的「hasAccess」函數,你不是假設調用「startSession」而不是「session_start」? – Touch 2013-04-22 13:47:56

+0

代碼中不存在「成功」這個短語。 – 2013-04-22 13:47:57

+0

@Touch我修復了這個問題,但沒有奏效。 MikeB對不起,請允許我澄清:我沒有收到任何錯誤 – mishmomo 2013-04-22 13:50:48

回答

0

你有沒有在你的index.php頁面的頂部有

<?php session_start(); ?> 

and var_dump($ _ SESSION);看看它有什麼信息

據我所知,你將不得不有session_start();在任何頁面上你想要你的會話信息存在。

0

您的邏輯錯誤。 if (!session_start())啓動會話,如果啓動失敗,則引發異常。您需要檢查用戶是否被授權了不同的方式,例如使用$this->user->status = $status;來確定用戶是否被授權。

1

除了我已經指出在頁面中間的「session_start()」作爲可能的邏輯錯誤,如果你說它是固定的,我對這條線有一種不好的感覺。

$stmt = $pdo->prepare('SELECT * FROM Users WHERE username = $this->user->username AND password = $this->user->password'); 

單引號可能會阻止$ this-> user中的變量被更改爲真實值。那不可能出現錯誤,但我更熟悉MySQLi,還沒有使用過PDO。但我建議你嘗試改變它:

$stmt = $pdo->prepare('SELECT * FROM Users WHERE username = '.$this->user->username.' AND password = '.$this->user->password); 

只是一個可能的提示。不知道它是否是唯一的。

+1

非常少的一點準備一個聲明,並將變量直接嵌入到準備中。或者做一個直接執行或做一個適當的準備如此:用戶名:密碼,然後' - > bindparam(「:用戶名」,$ this-> user->用戶名);'等 – Dave 2013-04-22 14:06:48

+0

我會+1(你似乎已經發現錯誤),但是你的建議讓他打開SQL注入攻擊。 [記住Bobby](http://xkcd.com/327/)。 – cwallenpoole 2013-04-22 14:08:36

+0

這是真的。我只是修復錯誤。考慮安全因素由她來決定。使用MySQLi,我會使用問號而不是綁定。但正如我所說,我還沒有使用過PDO。所以我只是向她展示了一個可能的解決辦法。由她來代替我的代碼來照顧SQL注入。但我已經注意到了,並且非常感謝你指出了它。我希望她看到它。 – Touch 2013-04-22 14:11:05