Skip to content

MySQL - 显示用户

MySQL 是一个多用户系统,这意味着它允许许多不同的用户同时连接并与数据库交互。恰当的用户管理是数据库管理、安全和审计的关键方面。本章涵盖如何列出现有用户并查看他们的权限(privileges)。

所有用户账户信息都存储在特殊的 mysql 系统数据库中的 user 表中。你可以直接使用 SELECT 语句查询此表,以查看所有已定义的用户。作为最佳实践,你应只选择你需要的列。

安全提示:对 mysql 数据库的访问应受到高度限制。通常,只有 root 等管理账户才能从这些表中读取数据。

在现代 MySQL 版本中,mysql.user 表中的列已发生变化。以下查询适用于 MySQL 8.0 及更高版本:

SELECT
User,
Host,
account_locked,
plugin AS authentication_plugin
FROM mysql.user;

输出将列出每个用户以及他们可以从哪个主机连接。localhost 主机意味着用户只能从与 MySQL 服务器相同的机器连接。

UserHostaccount_lockedauthentication_plugin
mysql.infoschemalocalhostYcaching_sha2_password
mysql.sessionlocalhostYcaching_sha2_password
mysql.syslocalhostYcaching_sha2_password
rootlocalhostNcaching_sha2_password
webapp%Ncaching_sha2_password

Host 列中的 ’%’ 通配符意味着用户可以从任何主机连接,使用时应谨慎。

仅仅列出用户是不够的;你通常需要知道用户被允许执行哪些操作。SHOW GRANTS 命令是查看用户权限(privileges)的正确且最安全的方式。

SHOW GRANTS FOR 'webapp'@'%';
-- 示例输出:
-- GRANT SELECT, INSERT, UPDATE ON `production_db`.* TO `webapp`@`%`

MySQL 提供了函数来识别当前连接的用户。它们之间存在细微但重要的区别:

  • USER(): 返回你连接服务器时指定的用户名和主机。
  • CURRENT_USER(): 返回你当前认证为的用户名和主机。在涉及代理或带有 DEFINER 子句的存储过程的情况下,这可能与 USER() 不同。
SELECT USER(), CURRENT_USER();
USER()CURRENT_USER()
root@localhostroot@localhost

要查看当前连接到服务器的用户以及他们在做什么,你可以查询 information_schema 数据库中的 processlist 表。这对于实时监控和故障排除非常有用。

SELECT
ID,
USER,
HOST,
DB,
COMMAND,
TIME,
STATE,
INFO AS `QUERY`
FROM information_schema.processlist;
IDUSERHOSTDBCOMMANDTIMESTATEQUERY
5event_schedulerlocalhostNULLDaemon3600Waiting for next activationNULL
9rootlocalhosttest_dbQuery0startingSELECT … FROM information_schema.processlist

以下示例展示了如何从不同的编程语言安全地查询 mysql.user 表。由于这些是只读操作且不涉及用户输入,因此 SQL 注入的风险较低,但使用一致的现代编码风格仍然很重要。

const mysql = require('mysql2/promise');
async function listUsers() {
let connection;
try {
connection = await mysql.createConnection({ host: 'localhost', user: 'root', password: 'my-secret-pw' });
const [rows, fields] = await connection.execute("SELECT User, Host FROM mysql.user");
console.log("MySQL Users:");
rows.forEach(row => {
console.log(`- User: ${row.User}, Host: ${row.Host}`);
});
} catch (error) {
console.error('Error listing users:', error);
} finally {
if (connection) await connection.end();
}
}
listUsers();
import mysql.connector
def list_users():
try:
conn = mysql.connector.connect(user='root', password='my-secret-pw', host='127.0.0.1')
cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT User, Host FROM mysql.user")
print("MySQL Users:")
for row in cursor.fetchall():
print(f"- User: {row['User']}, Host: {row['Host']}")
except mysql.connector.Error as err:
print(f"Error: {err}")
finally:
if 'conn' in locals() and conn.is_connected():
cursor.close()
conn.close()
if __name__ == "__main__":
list_users()