密碼 hash 之後,如何驗證
先在註冊頁面,一開始客戶輸入密碼後,就用 PHP 內建函式把密碼 hash,存到資料庫
password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
再到登入頁面,驗證密碼 hash 前後是否一樣
a. 原本的實作是從登入頁面抓取使用者輸入的帳號密碼,然後檢查資料庫裡面有沒有此使用者。
利用 echo $result->num_rows;,會輸出資料庫裡面有幾筆資料,輸出為零代表零筆資料,表示登入帳號或密碼有誤
輸出為一,代表有一筆資料,表示有找到帳號密碼
b. 但因要比對密碼 hash 前後的結果是否一樣,要先把資料庫裡的「hash 過後」的密碼抓出來,接著去拿使用者輸入的密碼,利用 password_verify('rasmuslerdorf', $hash)
,來比對兩個密碼是否相同。
首先註冊時,先經過內建函式 hash 密碼,再把密碼存進去。所以在資料庫裡面就會變成經過 hash 密碼
登入時,先透過 username 把密碼撈出來,先檢查是否有查到 user,沒有的話就錯誤返回;如果有查到使用者的話,把他的密碼拿出來,之後透 password_verify('rasmuslerdorf', $hash)
做比對,如果兩者相同,通過驗證的話,就登入成功,否則失敗。
改完之後好處,資料庫被偷,駭客不會知道原本是什麼。
就保護了使用者密碼。一般來說會經過 hash 才會存到裡面。
hw1 實作_1.密碼 hash
使用 PHP 內建 hash 函式
// 利用 password_hash()這個函式產生 hash 密碼
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
註冊跟登入時,驗證客戶端輸入的密碼是否跟資料庫加密後的密碼一致
<?php
session_start();
require_once('conn.php');
if (empty($_POST['username']) || empty($_POST['password'])) {
header('Location: login.php?errCode=1');
die();
}
$username = $_POST['username'];
$password = $_POST['password'];
// 把資料庫的使用者資料先撈出來
$sql = sprintf("SELECT * FROM christy_w9_users WHERE username = '%s'", $username);
$result = $conn->query($sql);
if (!$result) {
die($conn->error);
}
// 先驗證是否有此使用者,如果沒有的話,記得要 exit(),這樣下面的程式碼才不會被執行
if ($result->num_rows === 0) {
header('Location: login.php?errCode=2');
exit();
}
// 利用 PHP 內建的 password_verify() 來檢查客戶端輸入的密碼是否跟資料庫裡面 hash 過的密碼一致
$row = $result->fetch_assoc();
if (password_verify($password, $row['password'])) {
$_SESSION['username'] = $username;
header('Location: index.php');
} else {
header('Location: login.php?errCode=2');
}
?>
code_handle_login.php
<?php
session_start();
require_once('conn.php');
require_once('utils.php');
if (empty($_POST['username']) || empty($_POST['password'])) {
header('Location: login.php?errCode=1');
die();
}
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $username);
$result = $stmt->execute();
if (!$result) {
die($conn->error);
}
$result = $stmt->get_result();
if ($result->num_rows === 0) {
header('Location: login.php?errCode=2');
exit();
}
$row = $result->fetch_assoc();
if (password_verify($password, $row['password'])) {
$_SESSION['username'] = $username;
header('Location: index.php');
} else {
header('Location: login.php?errCode=2');
}
?>
code_handle_register.php
<?php
require_once('conn.php');
if (empty($_POST['nickname']) || empty($_POST['username']) || empty($_POST['password'])) {
header('Location: register.php?errCode=1');
die();
}
$nickname = $_POST['nickname'];
$username = $_POST['username'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$sql = sprintf("INSERT INTO users(nickname, username, password) VALUES('%s', '%s', '%s')", $nickname, $username, $password);
$result = $conn->query($sql);
if (!$result) {
$code = $conn->errno;
if ($code === 1062) {
header('Location: register.php?errCode=2');
}
die($conn->error);
}
header('Location: index.php');
?>