2016-07-11 8 views
1

Это моя первая пробная версия для внедрения сайта-участника с соленными паролями, которые все хранятся в БД (MySQL). Все работает, за исключением ошибки на странице «Логин для участников».Как убрать соленый пароль из базы данных и пользователя auth?

Ошибка: Логин пользователя страница принимает любую запись на членство на сайте и по какой-то причине проходит мой чек на $result === false

Это код для проверки, если существует элемент, пожалуйста, дайте мне знаете, в чем проблема:

$servername = 'localhost'; 
$username = 'root'; 
$pwd = ''; 
$dbname = 'lp001'; 

$connect = new mysqli($servername,$username,$pwd,$dbname); 

if ($connect->connect_error){ 
    die('connection failed, reason: '.$connect->connect_error); 
} 


$name = mysqli_real_escape_string($connect, $_POST['name']); 
$password = mysqli_real_escape_string($connect, $_POST['password']); 
$saltQuery = "SELECT salt FROM users WHERE name = '$name';"; 
$result = mysqli_query($connect, $saltQuery); 
if ($result === false){ 
    die(mysqli_error()); 
} 
$row = mysqli_fetch_assoc($result); 
$salt = $row['salt']; 

$saltedPW = $password.$salt; 
$hashedPW = hash('sha256', $saltedPW); 
$sqlQuery = "SELECT * FROM users WHERE name = '$name' AND password = '$hashedPW'"; 

if (mysqli_query($connect, $sqlQuery)){ 
    echo '<h1>Welcome to the member site '.$name.'</h1>'; 
}else{ 
    echo 'error adding the query: '.$sql_q.'<br> Reason: '.mysqli_error($connect); 
} 
+0

Смотрите это почти под ключ для Вас, раздел Логин, с 'password_verify()' здесь: http://stackoverflow.com/a/33665819. Она включает в себя сеанс, сообщения об ошибках и попытаться/поймать – Drew

+0

SHA- * алгоритмы не являются безопасными для хранения паролей, вместо того, чтобы использовать функцию [password_hash()] (http://www.php.net/manual/en/function. password-hash.php), чтобы создать безопасный хэшинг BCrypt. Это сделало бы неуместным хранить соль отдельно, посмотрите на это [ответ] (http://stackoverflow.com/a/27094183/575765). – martinstoeckli

+0

@martinstoeckli - спасибо, если вы можете написать это как код, я напишу его как ответ, который поможет мне и другим в будущем, и снова забудется. – clusterBuddy

ответ

2

Часто разработчики борются с проверкой пароля для входа в систему, поскольку они не уверены, как обращаться e сохраненный хэш пароля. Они знают, что пароль должен быть хэшируются с соответствующей функцией, как password_hash(), и хранить их в varchar(255) поле:

// Hash a new password for storing in the database. 
// The function automatically generates a cryptographically safe salt. 
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT); 

В форме входа, мы не можем проверить пароль непосредственно с SQL, и мы не можем найти его , потому что хранящиеся хеши соленые. Вместо этого мы ...

  1. должны прочитать пароль хэш-из базы данных, поиск по идентификатору пользователя
  2. , а затем может проверить пароль для входа на найденном хэш с функцией password_verify().

Ниже вы можете найти пример кода, показывающий, как сделать проверку пароля с подключением к MySQLi. Код не имеет проверки, чтобы сделать его читаемым ошибку:

/** 
* mysqli example for a login with a stored password-hash 
*/ 
$mysqli = new mysqli($dbHost, $dbUser, $dbPassword, $dbName); 
$mysqli->set_charset('utf8'); 

// Find the stored password hash in the db, searching by username 
$sql = 'SELECT password FROM users WHERE username = ?'; 
$stmt = $mysqli->prepare($sql); 
$stmt->bind_param('s', $_POST['username']); // it is safe to pass the user input unescaped 
$stmt->execute(); 

// If this user exists, fetch the password-hash and check it 
$isPasswordCorrect = false; 
$stmt->bind_result($hashFromDb); 
if ($stmt->fetch() === true) 
{ 
    // Check whether the entered password matches the stored hash. 
    // The salt and the cost factor will be extracted from $hashFromDb. 
    $isPasswordCorrect = password_verify($_POST['password'], $hashFromDb); 
} 

Обратите внимание, что пример использует подготовленные заявления, чтобы избежать SQL-инъекции, Экранирование не обязательно в этом случае. Эквивалентный пример для чтения из п.д.о. соединение может выглядеть следующим образом:

/** 
* pdo example for a login with a stored password-hash 
*/ 
$dsn = "mysql:host=$dbHost;dbname=$dbName;charset=utf8"; 
$pdo = new PDO($dsn, $dbUser, $dbPassword); 

// Find the stored password hash in the db, searching by username 
$sql = 'SELECT password FROM users WHERE username = ?'; 
$stmt = $pdo->prepare($sql); 
$stmt->bindValue(1, $_POST['username'], PDO::PARAM_STR); // it is safe to pass the user input unescaped 
$stmt->execute(); 

// If this user exists, fetch the password hash and check it 
$isPasswordCorrect = false; 
if (($row = $stmt->fetch(PDO::FETCH_ASSOC)) !== false) 
{ 
    $hashFromDb = $row['password']; 

    // Check whether the entered password matches the stored hash. 
    // The salt and the cost factor will be extracted from $hashFromDb. 
    $isPasswordCorrect = password_verify($_POST['password'], $hashFromDb); 
}