Hàm password_hash
Thực tế, hàm md5 và việc muối
mật khẩu bằng nó được coi là lỗi thời.
Chúng ta học nó để bạn hiểu tài liệu tiếp theo,
đồng thời bởi vì bạn có thể gặp phải
điều này khi làm việc với các dự án của người khác.
Tồn tại một cách hoàn thiện hơn để có được
một mật khẩu đã muối. Để làm điều này, sử dụng hàm
password_hash. Tham số đầu tiên nó
nhận một chuỗi, tham số thứ hai - thuật toán mã hóa
(sẽ nói sau), và trả về giá trị băm của chuỗi đó
cùng với muối.
Hãy thử chạy đoạn mã này vài lần:
<?php
echo password_hash('12345', PASSWORD_DEFAULT);
?>
Mỗi lần bạn sẽ nhận được một kết quả khác nhau và trong kết quả đó, phần đầu chuỗi sẽ là muối, còn phần thứ hai - mật khẩu đã muối.
Giả sử chúng ta có một giá trị băm, nhận được từ hàm
password_hash và một mật khẩu nào đó. Để
kiểm tra xem đó có phải là giá trị băm của mật khẩu này hay không,
cần sử dụng hàm password_verify
- tham số đầu tiên nó nhận mật khẩu,
tham số thứ hai - giá trị băm, và trả về true
hoặc false.
Hãy xem ví dụ:
<?php
$password = '12345'; // mật khẩu
$hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // giá trị băm
if (password_verify($password, $hash)) {
// giá trị băm từ mật khẩu này
} else {
// giá trị băm không phải từ mật khẩu này
}
?>
Điều này mang lại cho chúng ta điều gì trong thực tế: chúng ta có thể không cần tạo một trường riêng trong cơ sở dữ liệu để lưu trữ muối, không phải bận tâm với việc tạo ra muối này - PHP sẽ làm tất cả cho chúng ta!
Tức là, kết quả sẽ là trong cơ sở dữ liệu, tại trường
password chúng ta sẽ lưu trữ mật khẩu đã muối
cùng với muối của nó. Đồng thời, mật khẩu đã băm
sẽ có độ dài lớn hơn. Vì vậy
trong cơ sở dữ liệu, chúng ta cần sửa kích thước
trường chứa mật khẩu và đặt nó thành 60
ký tự.
Bây giờ hãy sửa mã đăng ký. Đây là những gì chúng ta có hiện tại:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // độ dài muối
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // ký tự từ bảng ASCII
}
return $salt;
}
$salt = generateSalt(); // muối
$password = md5($salt . $_POST['password']); // chuyển đổi mật khẩu thành giá trị băm đã muối
?>
Với password_hash, chúng ta có thể rút ngắn điều này xuống còn:
<?php
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
Tương tự, mã đăng nhập sẽ được điều chỉnh:
<?php
$login = $_POST['login'];
$query = "SELECT * FROM users WHERE login='$login'"; // lấy người dùng theo tên đăng nhập
$res = mysqli_query($link, $query);
$user = mysqli_fetch_assoc($res);
if (!empty($user)) {
$hash = $user['password']; // mật khẩu đã muối từ CSDL
// Kiểm tra sự tương ứng giữa giá trị băm từ cơ sở dữ liệu và mật khẩu đã nhập
if (password_verify($_POST['password'], $hash)) {
// tất cả ổn, tiến hành đăng nhập...
} else {
// mật khẩu không khớp, hiển thị thông báo
}
} else {
// không có người dùng với tên đăng nhập này, hiển thị thông báo
}
?>
Hãy chuyển đổi chức năng đăng nhập và đăng ký của bạn sang các hàm mới đã học.