Skip to content

MySQL - 修改密码

管理用户密码是 MySQL 中一项关键的安全任务。现代版本的 MySQL 提供了一种安全和标准化的方式来处理密码更改。本教程涵盖了最佳实践,并将其与过时方法进行对比。

ALTER USER 语句是在 MySQL 5.7.6 及更高版本中更改用户密码的推荐、安全且最可靠的方法。它使用用户配置的认证插件自动处理密码哈希。

ALTER USER 'username'@'hostname' IDENTIFIED BY 'new_plain_text_password';

您也可以更改当前登录用户的密码:

ALTER USER USER() IDENTIFIED BY 'new_plain_text_password';

首先,让我们创建一个新用户。在 MySQL 8+ 中,默认的认证插件是 caching_sha2_password,它比旧的 mysql_native_password 更安全。

CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'InitialP@ssw0rd123';

现在,让我们更改 app_user 的密码。

ALTER USER 'app_user'@'localhost' IDENTIFIED BY 'UpdatedS3cur3P@ss!';

服务器将响应:

Query OK, 0 rows affected (0.01 sec)

密码已更新。不需要 FLUSH PRIVILEGES。更改是即时且安全的。

遗留和已弃用的方法(在现代系统中应避免)

Section titled “遗留和已弃用的方法(在现代系统中应避免)”

SET PASSWORD 语句是更改密码的常用方法。虽然它仍然有效,但首选 ALTER USER,因为它提供了更多的账户管理选项,不仅仅是密码(例如,设置账户锁定、密码过期)。

-- 遗留语法
SET PASSWORD FOR 'app_user'@'localhost' = 'another_legacy_password';

2. 直接更新 mysql.user 表(强烈不推荐)

Section titled “2. 直接更新 mysql.user 表(强烈不推荐)”

在较旧的 MySQL 版本中,可以通过直接更新 mysql.user 系统表来更改密码。这现在被认为是非常糟糕的做法,在现代 MySQL 中不可靠,原因如下:

  • 绕过安全检查:它绕过了内部验证和密码管理逻辑。
  • 认证插件问题:它无法正确地与 caching_sha2_password 等认证插件交互。直接设置 authentication_string 列可能导致认证失败。
  • 废弃函数:PASSWORD() 函数(以前用于手动插入时对密码进行哈希处理)已弃用,并在 MySQL 8.0 中被移除。
-- 在现代 MySQL 中不要使用此方法
-- PASSWORD() 函数已移除,此方法不安全。
UPDATE mysql.user SET authentication_string = PASSWORD('bad_idea') WHERE User = 'app_user' AND Host = 'localhost';
FLUSH PRIVILEGES;

从应用程序中更改密码时,请始终使用 ALTER USER 语句。使用参数化查询以防止 SQL 注入,即使输入看起来是安全的。

此示例演示了如何从 Node.js 应用程序安全地更改用户密码。

const mysql = require('mysql2/promise');
async function changeUserPassword(adminConnection, username, hostname, newPassword) {
try {
// 为安全起见使用参数化查询,尽管此处的值是硬编码的。
const sql = 'ALTER USER ?@? IDENTIFIED BY ?';
const params = [username, hostname, newPassword];
await adminConnection.execute(sql, params);
console.log(`Password for user '${username}'@'${hostname}' changed successfully.`);
} catch (error) {
console.error('Failed to change password:', error);
throw error;
}
}
async function main() {
let connection;
try {
// 使用具有更改其他用户权限的用户(例如 root)连接
connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_root_password'
});
await changeUserPassword(connection, 'app_user', 'localhost', 'NewP@ssFromApp123');
} catch (err) {
console.error('An error occurred:', err);
} finally {
if (connection) connection.end();
}
}
main();