2012-10-04 121 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