MySQL - 显示权限
MySQL: 管理用户权限
Section titled “MySQL: 管理用户权限”在 MySQL 中,一个健壮的安全模型控制着用户可以执行的操作。访问通过一套权限系统进行管理。用户必须被授予适当的权限才能执行诸如选择数据、创建表或管理服务器等操作。
使用 SHOW PRIVILEGES 列出所有可用权限
Section titled “使用 SHOW PRIVILEGES 列出所有可用权限”SHOW PRIVILEGES 语句显示 MySQL 服务器支持的所有系统权限的完整列表。这有助于了解您可以授予用户的全部权限范围。
输出包含三列:
- Privilege: 权限名称(例如,
SELECT、CREATE USER)。 - Context: 权限适用的级别(例如,表、服务器管理、函数)。
- Comment: 权限的简要说明。
SHOW PRIVILEGES;执行此查询将列出您的 MySQL 服务器版本支持的所有权限。
SHOW PRIVILEGES;输出(节选)
Section titled “输出(节选)”输出将是一个很长的系统权限列表。以下是来自现代 MySQL 8.x 服务器的一小部分示例:
| Privilege | Context | Comment |
|---|---|---|
| Alter | Tables | 修改表 |
| Create user | Server Admin | 创建新用户 |
| Delete | Tables | 删除现有行 |
| Drop | Databases, Tables, Views | 删除数据库、表和视图 |
| Execute | Functions, Procedures | 执行存储例程 |
| Insert | Tables | 向表中插入数据 |
| Select | Tables | 从表中检索行 |
| Update | Tables | 更新现有行 |
| REPLICATION_SLAVE_ADMIN | Server Admin | 执行复制管理 |
使用 SHOW GRANTS 检查特定用户的授权
Section titled “使用 SHOW GRANTS 检查特定用户的授权”更常见的情况是,您会想查看已授予特定用户的具体权限。为此,SHOW GRANTS 命令是正确的工具。
SHOW GRANTS FOR 'username'@'hostname';让我们检查连接自任何主机 (%) 的用户 app_user 的权限。
SHOW GRANTS FOR 'app_user'@'%';+-------------------------------------------------------------------------+| Grants for app_user@% |+-------------------------------------------------------------------------+| GRANT USAGE ON *.* TO `app_user`@`%` || GRANT SELECT, INSERT, UPDATE ON `my_app_db`.* TO `app_user`@`%` |+-------------------------------------------------------------------------+此输出清楚地表明 app_user 具有基本连接权限 (USAGE),并且可以对 my_app_db 数据库中的所有表执行 SELECT、INSERT 和 UPDATE 操作。
以编程方式检查权限
Section titled “以编程方式检查权限”您也可以从应用程序代码中执行 SHOW GRANTS 以验证权限。以下是几种语言中的现代、安全示例。
最佳实践:环境变量
Section titled “最佳实践:环境变量”切勿在源代码中硬编码数据库凭据。使用环境变量(例如,从 .env 文件加载)来存储敏感信息,如用户名和密码。
PythonNode.jsPHPJava
此示例使用 `mysql-connector-python` 库和 `with` 语句进行自动资源管理。
**设置:** `pip install mysql-connector-python python-dotenv`
```pythonimport mysql.connectorimport osfrom dotenv import load_dotenv
load_dotenv() # Load variables from .env file
# --- 从环境变量配置 ---db_config = { 'host': os.getenv('DB_HOST'), 'user': os.getenv('DB_USER'), 'password': os.getenv('DB_PASSWORD'),}
user_to_check = 'app_user'host_to_check = '%'
try: # Use a 'with' statement for automatic connection closing with mysql.connector.connect(**db_config) as connection: with connection.cursor() as cursor: query = "SHOW GRANTS FOR %s@%s" cursor.execute(query, (user_to_check, host_to_check))
print(f"Privileges for {user_to_check}@{host_to_check}:") for grant in cursor: print(grant[0])
except mysql.connector.Error as e: print(f"Error connecting to MySQL: {e}")此示例使用 mysql2/promise 库和 async/await 来编写现代异步代码。
设置: npm install mysql2 dotenv
const mysql = require('mysql2/promise');require('dotenv').config(); // Load variables from .env file
// --- 从环境变量配置 ---const dbConfig = { host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD,};
const userToCheck = 'app_user';const hostToCheck = '%';
async function checkGrants() { let connection; try { connection = await mysql.createConnection(dbConfig); const query = 'SHOW GRANTS FOR ?@?'; const [rows] = await connection.execute(query, [userToCheck, hostToCheck]);
console.log(`Privileges for ${userToCheck}@${hostToCheck}:`); rows.forEach(row => { console.log(Object.values(row)[0]); });
} catch (error) { console.error(`Error connecting to or querying MySQL: ${error.message}`); } finally { if (connection) { await connection.end(); } }}
checkGrants();此示例使用现代 mysqli 扩展,采用面向对象风格并包含错误处理。
设置: 使用 Composer 管理依赖。
<?php// Use Composer's autoloader for libraries like a .env loader// require 'vendor/autoload.php';// $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);// $dotenv->load();
// --- 配置(最好来自环境变量)---$dbHost = getenv('DB_HOST');$dbUser = getenv('DB_USER');$dbPassword = getenv('DB_PASSWORD');
$userToCheck = 'app_user';$hostToCheck = '%';
// Enable exception reporting for mysqlimysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try { $mysqli = new mysqli($dbHost, $dbUser, $dbPassword);
// Use prepared statements even for SHOW GRANTS to be safe $stmt = $mysqli->prepare("SHOW GRANTS FOR ?@?"); $stmt->bind_param("ss", $userToCheck, $hostToCheck); $stmt->execute();
$result = $stmt->get_result();
echo "Privileges for {$userToCheck}@{$hostToCheck}:\n"; while ($row = $result->fetch_array()) { echo $row[0] . "\n"; }
$stmt->close(); $mysqli->close();
} catch (mysqli_sql_exception $e) { echo "Error: " . $e->getMessage() . "\n";}
?>此示例使用现代 JDBC,带有 try-with-resources 语句用于自动资源管理,并使用了 PreparedStatement。
设置: 使用 Maven 或 Gradle 等构建工具来包含 MySQL JDBC 驱动依赖。
import java.sql.*;
public class ShowGrantsExample { public static void main(String[] args) { // --- 配置(最好来自属性文件或环境变量)--- String url = "jdbc:mysql://" + System.getenv("DB_HOST") + ":3306/"; String user = System.getenv("DB_USER"); String password = System.getenv("DB_PASSWORD");
String userToCheck = "app_user"; String hostToCheck = "%"; String sql = "SHOW GRANTS FOR ?@?";
// Use try-with-resources for automatic closing of Connection, PreparedStatement, and ResultSet try (Connection conn = DriverManager.getConnection(url, user, password); PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, userToCheck); pstmt.setString(2, hostToCheck);
try (ResultSet rs = pstmt.executeQuery()) { System.out.printf("Privileges for %s@%s:%n", userToCheck, hostToCheck); while (rs.next()) { System.out.println(rs.getString(1)); } } } catch (SQLException e) { System.err.println("Database Error: " + e.getMessage()); } }}