2017-03-27 58 views
1

這裏是登錄代碼,我試圖讓密碼驗證工作,但它不想。這似乎是這個count($sql->fetchAll()) > 0是問題或我打電話給password_verify()錯誤的變量。無法獲得用戶輸入到password_verify()

$signup = isset($_POST['signup']) ? $_POST['signup'] : false; 
$submit = isset($_POST['submit']) ? $_POST['submit'] : false; 
$username = isset($_POST['username']) ? $_POST['username'] : false; 
$password = isset($_POST['password']) ? $_POST['password'] : false; 

if($submit && $username && $password) { 

    $sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name AND user_pass=:user_pass"); 
    $sql->bindParam(':user_name', $username, PDO::PARAM_STR); 
    $sql->bindParam(':user_pass', $password, PDO::PARAM_STR); 
    $check_user=$sql->fetch(PDO::FETCH_ASSOC); 
    $success = $sql->execute(); 
    $verify = password_verify($password, check_user['user_pass']); 
    // Successfully logged in! 
    if($success && count($sql->fetchAll()) > 0 && $verify) { 

    $_SESSION['logged_in'] = true; 
    // Unset errors 
    unset($_SESSION['error']); 
    } 
    else { 
    // display an error 
    $_SESSION['error'] = 'That user doesn\'t exist'; 
    } 
} 
else { 
    //displays error 
    $_SESSION['error'] = 'Please enter all fields'; 
} 
if($signup) { 
    header('Location: signup.php'); 
} 
exit; 

下面是註冊代碼

function register($uname,$umail,$upass) 
    { 

     $DB_con = null; 

try 
{ 
    $DB_con = new PDO("mysql:host=$host;dbname=$dbname", "$username" ,"$password"); 
    $DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
} 
catch(PDOException $e) 
{ 
    echo $e->getMessage(); 
} 



     try 
     { 
      $new_password = password_hash($upass, PASSWORD_DEFAULT); 

      $stmt = $DB_con->prepare("INSERT INTO users(user_name,user_email,user_pass) 
                 VALUES(:uname, :umail, :upass)"); 

      $stmt->bindparam(":uname", $uname); 
      $stmt->bindparam(":umail", $umail); 
      $stmt->bindparam(":upass", $new_password);    
      $stmt->execute(); 
      return $stmt; 

     } 
     catch(PDOException $e) 
     { 
      echo $e->getMessage(); 
     }  

    } 
+0

我可以看到兩件事:驗證中在'check_user'中缺少'$',並且在執行之前提取。 – Qirel

+0

註冊函數中的語法錯誤,請參閱突出顯示 – Qirel

+0

噢,另一種方法是:您正在嘗試選擇密碼與未加密密碼匹配的位置,但在使用'password_hash()'時不能這樣做。從你的where子句中刪除密碼 – Qirel

回答

0

有幾件事情需要與這段代碼被清理。

讓我們從您的register()函數開始。這裏有一個明確的語法錯誤(你在哪裏建立連接),""$password"。那麼該函數不知道什麼$dbname,$username$password(用於連接),這些變量不在函數的範圍(它可以看到它)。通常最好將連接對象作爲參數傳遞,而不是每次調用register()函數時創建一個新對象。修改爲和清理了一下,應該是這樣的

function register($DB_con, $uname ,$umail, $upass) { 
    try { 
     $new_password = password_hash($upass, PASSWORD_DEFAULT); 

     $stmt = $DB_con->prepare("INSERT INTO users (user_name, user_email, user_pass) 
                VALUES (:uname, :umail, :upass)"); 

     $stmt->bindparam(":uname", $uname); 
     $stmt->bindparam(":umail", $umail); 
     $stmt->bindparam(":upass", $new_password);    
     return $stmt->execute(); 

    } catch(PDOException $e) { 
     echo $e->getMessage(); 
    } 
} 

和像

register($DB_con, 'Nader', '[email protected]', 'pa$$w0rd'); // True or false 

然後使用到你的登錄。這有點混亂,你做錯了一些事情。什麼我發現迄今...

  • 抓取執行
  • 選擇WHERE後的散列的口令等於一個散列(不會返回任何行)
  • count($sql->fetchAll()) > 0會零,因爲你已經提取了一次,並且只有一個用戶=>這意味着一行。獲取一個意味着沒有更多的獲取,所以fetchAll()是空的!
  • 你不需要做任何更多的檢查比對if ($check_user=$sql->fetch())檢查是否有行

更正及以上的佔了點,你的代碼會是這個樣子

$signup = isset($_POST['signup']) ? $_POST['signup'] : false; 
$submit = isset($_POST['submit']) ? $_POST['submit'] : false; 
$username = isset($_POST['username']) ? $_POST['username'] : false; 
$password = isset($_POST['password']) ? $_POST['password'] : false; 

if ($submit && $username && $password) { 
    $sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name"); 
    $sql->bindParam(':user_name', $username, PDO::PARAM_STR); 
    $sql->execute(); 

    if ($check_user=$sql->fetch(PDO::FETCH_ASSOC)) { 
     if (password_verify($password, $check_user['user_pass'])) { 
      $_SESSION['logged_in'] = true; 
      // Unset errors 
      unset($_SESSION['error']); 
     } else { 
      // Invalid password 
     } 
    } else { 
     // No user with that username 
    } 
} else { 
    //displays error 
    $_SESSION['error'] = 'Please enter all fields'; 
} 

if ($signup) { 
    header('Location: signup.php'); 
} 
exit; 

這是假設唯一的用戶名在DB

有可能通過在你的文件的頂部添加

<?php 
error_reoprting(E_ALL); 
ini_set("display_errors", 1); 

是更多的問題,我看不出,這就是爲什麼你應該啓用錯誤報告(錯誤不應該在實際環境中顯示的那樣)。

+0

嗨,非常感謝你的幫助,現在正在工作。我對PHP真的很陌生,所以我嘗試了很多不同的東西,因此代碼很亂,非常感謝你花時間修改它。至於數據庫連接,我將實際值更改爲$ dbname等等,因爲它具有我的uni憑據作爲值。事後看來,我應該用不同的方式來表達這些價值觀,我會在下一次記住這一點。 –

+0

樂意幫忙!我們都從某個地方開始;-)使用參數化查詢和正確的密碼散列法,您可以開始使用PDO,這樣就可以繼續! *豎起大拇指*如果此答案爲您提供了一個很好的解決方案,請確保upvote和[接受答案](http://stackoverflow.com/help/accepted-answer)! *乾杯*! :-) – Qirel

+0

我會的,再次感謝你:D! –