2016-11-25 3 views
0

私は私のウェブにパスワードを忘れたシステムを置き、それは働いています。パスワードはデータベース上で変更されます。しかし、私はログインできません。 password_verifyは新しいパスワードを確認できません。何が足りないの?私のログイン機能は私の変更されたパスワードを確認できません

これは私のforgotpass.php

//Password submiting 
     case 3: 
      //we are submitting a new password (only for encrypted) 
      if ($_POST['userID'] == '' || $_POST['key'] == '') header("location: login.php"); 
      if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '') 
      { 
       $error = true; 
       $show = 'recoverForm'; 
      } else { 
       $error = false; 
       $show = 'recoverSuccess'; 
       updateUserPassword($_POST['userID'],$_POST['pw0'],$_POST['key']); 
      } 
     break; 
    } 
} 
     elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") { 
    $show = 'invalidKey'; 
    $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u']))); 

case 'recoverForm': ?> 
    <h2>Password Recovery</h2> 
    <p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['userID'] : $securityUser); ?>.</p> 
    <p>In the fields below, enter your new password.</p> 
    <?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?> 
    <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> 
     <div class="fieldGroup"><label for="pw0">New Password</label><div class="field"><input type="password" class="input" name="pw0" id="pw0" value="" maxlength="20"></div></div> 
     <div class="fieldGroup"><label for="pw1">Confirm Password</label><div class="field"><input type="password" class="input" name="pw1" id="pw1" value="" maxlength="20"></div></div> 
     <input type="hidden" name="subStep" value="3" /> 
     <input type="hidden" name="userID" value="<?= $securityUser=='' ? $_POST['userID'] : $securityUser; ?>" /> 
     <input type="hidden" name="key" value="<?= $_GET['email']=='' ? $_POST['key'] : $_GET['email']; ?>" /> 
     <div class="fieldGroup"><input type="submit" value="Submit" style="margin-left: 150px;" /></div> 
     <div class="clear"></div> 
    </form> 

であり、これが私のfunctions.php(機能付きログインするとリカバリパスへ)

function login($email, $password, $mysqli) { 
    // Using prepared statements means that SQL injection is not possible. 

    if ($stmt = $mysqli->prepare("SELECT id, username, password 
     FROM users 
     WHERE email = ? 
     LIMIT 1")) { 
     $stmt->bind_param('s', $email); // Bind "$email" to parameter. 
     $stmt->execute(); // Execute the prepared query. 
     $stmt->store_result(); 

     // get variables from result. 
     $stmt->bind_result($user_id, $username, $db_password); 
     $stmt->fetch(); 

     if ($stmt->num_rows == 1) { 
      // If the user exists we check if the account is locked 
      // from too many login attempts 

      if (checkbrute($user_id, $mysqli) == true) { 
       // Account is locked 
       // Send an email to user saying their account is locked 
       return false; 
      } else { 
       // Check if the password in the database matches 
       // the password the user submitted. We are using 
       // the password_verify function to avoid timing attacks. 
       if (password_verify($password, $db_password)) { 
        // Password is correct! 
        // Get the user-agent string of the user. 
        $user_browser = $_SERVER['HTTP_USER_AGENT']; 
        // XSS protection as we might print this value 
        $user_id = preg_replace("/[^0-9]+/", "", $user_id); 
        $_SESSION['user_id'] = $user_id; 
        // XSS protection as we might print this value 
        $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                   "", 
                   $username); 
        $_SESSION['username'] = $username; 
        $_SESSION['email'] = $email; 
        $_SESSION['login_string'] = hash('sha512', 
           $db_password . $user_browser); 
        // Login successful. 
        return true; 
       } else { 
        // Password is not correct 
        // We record this attempt in the database 
        $now = time(); 
        $mysqli->query("INSERT INTO login_attempts(user_id, time) 
            VALUES ('$user_id', '$now')"); 
        return false; 
       } 
      } 
     } else { 
      // No user exists. 
      return false; 
     } 
    } 
} 




function login_check($mysqli) { 
    // Check if all session variables are set 

    if (isset($_SESSION['user_id'], 
         $_SESSION['username'], 
         $_SESSION['email'], 
         $_SESSION['login_string'])) { 

     $user_id = $_SESSION['user_id']; 
     $login_string = $_SESSION['login_string']; 
     $username = $_SESSION['username']; 
     $email= $_SESSION['email']; 

     // Get the user-agent string of the user. 
     $user_browser = $_SERVER['HTTP_USER_AGENT']; 

     if ($stmt = $mysqli->prepare("SELECT password 
             FROM users 
             WHERE id = ? LIMIT 1")) { 
      // Bind "$user_id" to parameter. 
      $stmt->bind_param('i', $user_id); 
      $stmt->execute(); // Execute the prepared query. 
      $stmt->store_result(); 

      if ($stmt->num_rows == 1) { 
       // If the user exists get variables from result. 
       $stmt->bind_result($password); 
       $stmt->fetch(); 
       $login_check = hash('sha512', $password . $user_browser); 

       if (hash_equals($login_check, $login_string)){ 
        // Logged In!!!! 
        return true; 
       } else { 
        // Not logged in 
        return false; 
       } 
      } else { 
       // Not logged in 
       return false; 
      } 
     } else { 
      // Not logged in 
      return false; 
     } 
    } else { 
     // Not logged in 
     return false; 
    } 
} 

function checkUNEmail($uname,$email) 
{ 
    global $mysqli; 
    $error = array('status'=>false,'userID'=>0); 
    if (isset($email) && trim($email) != '') { 
     //email was entered 
     if ($stmt = $mysqli->prepare ("SELECT `ID` FROM `users` WHERE `Email` = ? LIMIT 1")) 
     { 
      $stmt->bind_param('s',trim($email)); 
      $stmt->execute(); 
      $stmt->store_result(); 
      $numRows = $stmt->num_rows(); 
      $stmt->bind_result($userID); 
      $stmt->fetch(); 
      $stmt->close(); 
      if ($numRows >= 1) return array('status'=>true,'userID'=>$userID); 
     } else { return $error; } 
    } elseif (isset($uname) && trim($uname) != '') { 
     //username was entered 
     if ($stmt = $mysqli->prepare("SELECT `ID` FROM `users` WHERE Username = ? LIMIT 1")) 
     { 
      $stmt->bind_param('s',trim($uname)); 
      $stmt->execute(); 
      $stmt->store_result(); 
      $numRows = $stmt->num_rows(); 
      $stmt->bind_result($userID); 
      $stmt->fetch(); 
      $stmt->close(); 
      if ($numRows >= 1) return array('status'=>true,'userID'=>$userID); 
     } else { return $error; } 
    } else { 
     //nothing was entered; 
     return $error; 
    } 
} 



function sendPasswordEmail($userID) 
{ 
    global $mysqli; 
    if ($stmt = $mysqli->prepare("SELECT `Username`,`Email`,`Password` FROM `users` WHERE `ID` = ? LIMIT 1")) 
    { 
     $stmt->bind_param('i',$userID); 
     $stmt->execute(); 
     $stmt->store_result(); 
     $stmt->bind_result($uname,$email,$pword); 
     $stmt->fetch(); 
     $stmt->close(); 
     $expFormat = mktime(date("H"), date("i"), date("s"), date("m") , date("d")+3, date("Y")); 
     $expDate = date("Y-m-d H:i:s",$expFormat); 
     $key = md5($uname . '_' . $email . rand(0,10000) .$expDate . PW_SALT); 
     if ($stmt = $mysqli->prepare("INSERT INTO `recoveryemails_enc` (`UserID`,`Key`,`expDate`) VALUES (?,?,?)")) 
     { 
      $stmt->bind_param('iss',$userID,$key,$expDate); 
      $stmt->execute(); 
      $stmt->close(); 
      $passwordLink = "<a href=\"?a=recover&email=" . $key . "&u=" . urlencode(base64_encode($userID)) . "\">http://www.oursite.com/forgotPass.php?a=recover&email=" . $key . "&u=" . urlencode(base64_encode($userID)) . "</a>"; 
      $message = "Dear $uname,\r\n"; 
      $message .= "Please visit the following link to reset your password:\r\n"; 
      $message .= "-----------------------\r\n"; 
      $message .= "$passwordLink\r\n"; 
      $message .= "-----------------------\r\n"; 
      $message .= "Please be sure to copy the entire link into your browser. The link will expire after 3 days for security reasons.\r\n\r\n"; 
      $message .= "If you did not request this forgotten password email, no action is needed, your password will not be reset as long as the link above is not visited. However, you may want to log into your account and change your security password and answer, as someone may have guessed it.\r\n\r\n"; 
      $message .= "Thanks,\r\n"; 
      $message .= "-- Our site team"; 
      $headers = ''; 
      $headers .= "From: Our Site <[email protected]> \n"; 
      $headers .= "To-Sender: \n"; 
      $headers .= "X-Mailer: PHP\n"; // mailer 
      $headers .= "Reply-To: [email protected]\n"; // Reply address 
      $headers .= "Return-Path: [email protected]\n"; //Return Path for errors 
      $headers .= "Content-Type: text/html; charset=iso-8859-1"; //Enc-type 
      $subject = "Your Lost Password"; 
      @mail($email,$subject,$message,$headers); 
      return str_replace("\r\n","<br/ >",$message); 
     } 
    } 
} 

function checkEmailKey($key,$userID) 
{ 
    global $mysqli; 
    $curDate = date("Y-m-d H:i:s"); 
    if ($stmt = $mysqli->prepare("SELECT `UserID` FROM `recoveryemails_enc` WHERE `Key` = ? AND `UserID` = ? AND `expDate` >= ?")) 
    { 
     $stmt->bind_param('sis',$key,$userID,$curDate); 
     $stmt->execute(); 
     $stmt->execute(); 
     $stmt->store_result(); 
     $numRows = $stmt->num_rows(); 
     $stmt->bind_result($userID); 
     $stmt->fetch(); 
     $stmt->close(); 
     if ($numRows > 0 && $userID != '') 
     { 
      return array('status'=>true,'userID'=>$userID); 
     } 
    } 
    return false; 
} 

function updateUserPassword($userID,$password,$key) 
{ 
    global $mysqli; 
    if (checkEmailKey($key,$userID) === false) return false; 
    if ($stmt = $mysqli->prepare("UPDATE `users` SET `Password` = ? WHERE `ID` = ?")) 
    { 
     $password = password_hash($password, PASSWORD_BCRYPT); 
     $stmt->bind_param('si',$password,$userID); 
     $stmt->execute(); 
     $stmt->close(); 
     $stmt = $mysqli->prepare("DELETE FROM `recoveryemails_enc` WHERE `Key` = ?"); 
     $stmt->bind_param('s',$key); 
     $stmt->execute(); 
    } 
} 

function getUserName($userID) 
{ 
    global $mysqli; 
    if ($stmt = $mysqli->prepare("SELECT `Username` FROM `users` WHERE `ID` = ?")) 
    { 
     $stmt->bind_param('i',$userID); 
     $stmt->execute(); 
     $stmt->store_result(); 
     $stmt->bind_result($uname); 
     $stmt->fetch(); 
     $stmt->close(); 
    } 
    return $uname; 
} 

パスをクリートするためのコードです登録プロセスについて

// Create hashed password using the password_hash function. 
     // This function salts it with a random salt and can be verified with 
     // the password_verify function. 
     $password = password_hash($password, PASSWORD_BCRYPT); 

     // Insert the new user into the database 
     if ($insert_stmt = $mysqli->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)")) { 
      $insert_stmt->bind_param('sss', $username, $email, $password); 
+2

大規模なコードレビューを作成するのではなく、これを小さな質問に減らすことはできますか?可能であれば、問題のコードを少数のコードに煮詰めてみてください。そのプロセスで何が起こっているのか把握するのに役立つかもしれません。 – WEBjuju

+0

不要なコードはすべて削除します。私は問題は、新しいパスワードが作成される方法にあると思う。ハッシュされていますが、正しい方法ではないかもしれません。 –

答えて

1

わかりました。私はこの問題を発見したと思います。私は、この行があなたの注意を必要と信じている:

$login_check = hash('sha512', $password . $user_browser); 

私はSHA512ハッシュを作成し、非常に遠くあなたを得るために起こっているの比較はないと思うので、あなたが実際にpassword_hashとbcryptのを使用してハッシュを作成しました。 password_hashで作成されたハッシュを検証する適切な方法は、password_verifyです。返されたハッシュの一部としてアルゴリズム、コストと塩を返します()は、この例にfrom the PHP documentation on password_verify()

if (password_verify('rasmuslerdorf', $hash)) { 
    echo 'Password is valid!'; 
} else { 
    echo 'Invalid password.'; 
} 

を参照してください。そして、その

password_hashに注意してください。したがって、ハッシュを検証するために必要なすべての情報が含まれています。これにより、ベリファイ機能は、塩またはアルゴリズム情報のための別個の記憶装置を必要とせずにハッシュを検証することができる。登録前と後の

とPWパスワードを更新した後にチェックし、ハッシュが良いことを確認するために登録した後

$password = '<PUT PASSWORD OF NEW USER HERE>'; 
$query = 'select password hash from users where id = <PUT ID OF NEW USER HERE>'; 
$res = mysqli_query($db, $query); 
echo $row['hash'].' '.((password_verify($password, $row['hash']))?'hash is good!':'no, no match on hash').'<br>'; 

チェックを更新します。

+0

しかし、私はパスワードverifiengを使用しています(password_verify($ password、$ db_password)){...そしてシステムはパスワードが変更されたときにいくつかの問題が発生しました。 –

+0

大丈夫です。登録時にユーザーパスワードを設定して、忘れたシーケンスと比較できるコード行を呼び出すことができますか? – WEBjuju

+0

あなたの時間をThnak。私は上記の質問にコードを投稿 –

関連する問題