2012-10-04 67 views
1

所以我有一個PHP身份驗證腳本,一切工作正常。但是我對我編程的方式非常不確定(我對一些東西進行了硬編碼),我希望堆棧能夠通過這個方式來查看並指出任何潛在的問題。PHP登錄驗證與BCrypt

下面是腳本:

<?php 
require_once 'Bcrypt.php'; 
class Mysql { 
    private $conn; 

    function __construct() { 
     $this->conn = new PDO('mysql:host=***;dbname=***;charset=UTF-8','***','***') or 
         die('There was a problem connecting to the database.'); 
    } 

    function verify_Username_and_Pass($un, $pwd) { 
     ini_set('display_errors', 'On'); 
     error_reporting(E_ALL | E_STRICT); 
     $query = "SELECT * 
       FROM Conference 
       WHERE Username = :un"; 

     $stmt = $this->conn->prepare($query); 

     $stmt->bindParam(':un', $un); 
     //$stmt->bindParam(':pwd', $pwd); 
     $stmt->execute(); 
     $row = $stmt->fetchAll(); 
     $hash = $row[0]["Password"]; 
     $is_correct = Bcrypt::check($pwd, $hash); 

     if ($is_correct) { 
      // User exist 
      $firstName = $row[0]["First Name"]; 
      $_SESSION["FirstName"] = $firstName; 
      return true; 
      $stmt->close(); 
     } 
     else { 
      // User doesn't exist 
      return false; 
      $stmt->close(); 
     } 
    } 
} 
?> 

那麼它是怎樣看?

+2

您應該嘗試在http://codereview.stackexchange.com/上提出此問題 – Tchoupi

回答

1

沒有測試它,我覺得你的代碼應該工作,BCrypt的使用看起來是合理的。當然有一些可以改進的地方,有些可能是意見的問題。

  1. 如果您的查詢沒有返回任何行(因爲沒有這樣的用戶名存在),您將訪問無效索引$row[0]["Password"]。在使用之前,您應該首先詢問是否有結果。
  2. 您關閉數據庫的呼叫位於return語句之後,因此它永遠不會被執行。 PHP將自動關閉數據庫,因此可以在return語句之前將其關閉,或者刪除該行。
  3. 您將函數命名爲verify_username_and_password(),但實際上它也讀取數據庫並寫入會話。這些是隱藏的活動,除非他讀取整個代碼,否則另一個開發人員無法知道會話更改。解決這個問題的一個可能性就是分解功能。

未經測試的例子:

$userRow = getUserRowFromDatabase($userName); 
if (!is_null($userRow)) 
{ 
    if (verifyPassword($password, $userRow["Password"])) 
    { 
    addLoggedInUserToSession($userRow["First Name"]) 
    } 
} 

的這三個功能中的每隻有一個需要解決的問題。這會讓你的代碼更具可讀性,理想情況下它應該像讀一本書中的故事一樣。

希望我能給你一些想法。

0

實際上,你可以使用MySQL來驗證哈希你

SELECT COUNT(*) FROM Conference 
WHERE Username = :un 
AND Password = ENCRYPT(:pass, Password) 
LIMIT 1