[英]PHP Password Rehashing in User Class (MySQL)
因此,我正在處理合並重新散列以將用戶升級為擁有 bcrypt 密碼的功能,並將其合並到我發現並已成功設置的現有 class 中,這太棒了。
但是,這個 class 缺少重新哈希檢查,這對於現有用戶數據庫上的舊密碼來說是很糟糕的。 我們需要處理 SHA1 密碼! 我們使用SHA1 + Salt ,所以我希望這可以轉換。
我使用這個 class 在這里找到:
https://alexwebdevelop.com/user-authentication/
所以使用這個 class,我添加了以下公共 function:
public function authenticate($username, $password)
{
/* Global $pdo object */
global $pdo;
// Database lookup
$stmt = $pdo->prepare("SELECT id, password, legacy_password FROM users WHERE username = ?");
$stmt->execute([$username]);
$stored = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$stored) {
// No such user, throw an exception
throw new Exception('Invalid user.');
}
if ($stored['legacy_password']) {
// This is the legacy password upgrade code
if (password_verify(sha1($password), $stored['password'])) {
$newHash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET password = ?, legacy_password = FALSE WHERE id = ?");
$stmt->execute([$newhash, $stored['id']]);
// Return the user ID (integer)
return $stored['id'];
}
} elseif (password_verify($password, $stored['password'])) {
// This is the general purpose upgrade code e.g. if a future version of PHP upgrades to Argon2
if (password_needs_rehash($stored['password'], PASSWORD_DEFAULT)) {
$newhash = password_hash($password, PASSWORD_BCRYPT);
$stmt = $pdo->prepare("UPDATE users SET password = ? WHERE id = ?");
$stmt->execute([$newhash, $stored['id']]);
}
// Return the user ID (integer)
return $stored['id'];
}
// When all else fails, throw an exception
throw new Exception('Rehashing failed.');
}
現在在 class 的 login() function 里面,我已經替換了
public function login($name, $passwd)
{
...
if (is_array($row)) {
if (password_verify($passwd, $row['password'])) {
/* Authentication succeeded. Set the class properties (id and name) */
$this->id = intval($row['id'], 10);
$this->name = $name;
$this->authenticated = TRUE;
/* Register the current Sessions on the database */
$this->registerLoginSession();
/* Finally, Return TRUE */
return TRUE;
}
}
}
有了這個:
public function login($name, $passwd)
{
...
if (is_array($row)) {
$userid = $this->authenticate($name, $row['password']);
if (password_verify($passwd, $row['password'])) {
/* Authentication succeeded. Set the class properties (id and name) */
$this->id = intval($userid);
$this->name = $name;
$this->authenticated = TRUE;
/* Register the current Sessions on the database */
$this->registerLoginSession();
/* Finally, Return TRUE */
return TRUE;
}
}
}
因此,它應該在檢查/重新散列后將手返回 ID。 所以它發現我是一個用戶,經過測試。 好..所以現在所有 authenticate() 所做的都是拋出失敗的異常錯誤。 我不知道如何從中獲取錯誤消息。
這似乎與此 ID 的確切關系,我做錯了什么?
這一點:用戶使用表單中的 SHA1(加鹽)密碼登錄,腳本重新哈希密碼,用戶登錄就像什么都沒發生一樣。
authenticate()轉換 function 我正在使用:
https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016#legacy-hashes
我很抱歉! 我從這里的建議中學到了東西,我感謝所有的幫助!
所以我自己解決了這個問題。 我所做的是刪除 authenticate() function,而是根據反饋意見直接解決了這個問題(我完全同意)。
我用這個替換了帖子中的最后一個代碼塊:
if (is_array($row)) {
if (password_needs_rehash($row['password'], PASSWORD_DEFAULT)) {
$newhash = password_hash($passwd, PASSWORD_BCRYPT);
$stmt = $pdo->prepare("UPDATE users SET password = ? WHERE id = ?");
$stmt->execute([$newhash, $row['id']]);
}
if (password_verify($passwd, $row['password'])) {
/* Authentication succeeded. Set the class properties (id and name) */
$this->id = intval($row['id'], 10);
$this->name = $name;
$this->authenticated = TRUE;
/* Register the current Sessions on the database */
$this->registerLoginSession();
/* Finally, Return TRUE */
return TRUE;
}
}
並且用戶密碼正在重新散列,並登錄!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.