Skip to content

MySQL - 解锁用户账户

锁定用户账户是 MySQL 中一项重要的安全功能。它允许管理员在不删除账户的情况下临时禁用账户,从而阻止登录和访问。这对于响应可疑活动、处理离职员工或强制执行安全策略非常有用。

用户的锁定状态存储在 mysql.user 系统表的 account_locked 列中。值为 ‘Y’ 表示账户已锁定,值为 ‘N’ 表示账户已解锁。

SELECT
User,
Host,
account_locked
FROM
mysql.user
WHERE
User = 'app_user';

默认情况下,MySQL 中创建的所有新用户账户都处于未锁定状态。

如果账户被锁定,您可以使用带有 ACCOUNT UNLOCK 子句的 ALTER USER 语句来解锁它。您必须拥有 CREATE USER 权限才能执行此命令。

ALTER USER 'username'@'hostname' ACCOUNT UNLOCK;

假设用户 app_user@'localhost' 当前已被锁定。我们可以按如下方式解锁它:

ALTER USER 'app_user'@'localhost' ACCOUNT UNLOCK;

运行命令后,您可以验证状态是否已更改。

SELECT User, Host, account_locked FROM mysql.user WHERE User = 'app_user';
-- 预期输出:
-- +----------+-----------+----------------+
-- | User | Host | account_locked |
-- +----------+-----------+----------------+
-- | app_user | localhost | N |
-- +----------+-----------+----------------+

同样,您可以使用 ACCOUNT LOCK 子句显式锁定账户。

ALTER USER 'app_user'@'localhost' ACCOUNT LOCK;

如果锁定的用户尝试连接,他们将收到 Access denied 错误(具体来说是错误 3118)。

以下是如何使用各种编程语言解锁用户账户的现代、健壮的示例。这些示例包括适当的错误处理和资源管理。

此示例使用 async/await 来编写简洁、现代的异步代码。

const mysql = require('mysql2/promise');
async function unlockUser(username, host) {
let connection;
try {
connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_root_password'
});
const query = 'ALTER USER ?@? ACCOUNT UNLOCK';
await connection.execute(query, [username, host]);
console.log(`User '${username}@${host}' has been unlocked successfully.`);
} catch (error) {
console.error(`Failed to unlock user: ${error.message}`);
} finally {
if (connection) {
await connection.end();
}
}
}
unlockUser('app_user', 'localhost');

此示例使用 with 语句来自动处理连接和游标。

import mysql.connector
from mysql.connector import errorcode
def unlock_user(username, host):
config = {
'user': 'root',
'password': 'your_root_password',
'host': 'localhost',
}
try:
with mysql.connector.connect(**config) as connection:
with connection.cursor() as cursor:
query = f"ALTER USER '{username}'@'{host}' ACCOUNT UNLOCK"
cursor.execute(query)
connection.commit()
print(f"User '{username}@{host}' has been unlocked successfully.")
except mysql.connector.Error as err:
print(f"Failed to unlock user: {err}")
unlock_user('app_user', 'localhost')

Java(使用 JDBC 和 try-with-resources)

Section titled “Java(使用 JDBC 和 try-with-resources)”

这个现代 Java 示例使用 try-with-resources 来确保数据库资源自动关闭。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class UserUnlocker {
private static final String DB_URL = "jdbc:mysql://localhost:3306/?user=root&password=your_root_password";
public void unlockUser(String username, String host) {
String query = String.format("ALTER USER '%s'@'%s' ACCOUNT UNLOCK", username, host);
try (Connection conn = DriverManager.getConnection(DB_URL);
Statement stmt = conn.createStatement()) {
stmt.executeUpdate(query);
System.out.printf("User '%s@%s' has been unlocked successfully.%n", username, host);
} catch (SQLException e) {
System.err.println("Failed to unlock user: " + e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
new UserUnlocker().unlockUser("app_user", "localhost");
}
}