Skip to content

MySQL - 撤销权限

REVOKE 语句是一个关键的数据控制语言(DCL)命令,用于从 MySQL 用户账户或角色中移除权限。它是 GRANT 语句的对应命令,对于实施最小权限安全原则至关重要,该原则规定用户应仅拥有执行其工作所需的精确权限,不多也不少。

您可以在不同级别撤销特定权限:全局 (*.*)、数据库 (database.*)、表 (database.table),甚至列级别。

REVOKE privilege_type [(column_list)]
ON object_type
FROM user_or_role;

例如:

REVOKE SELECT, INSERT ON my_app_db.products FROM 'app_user'@'localhost';

首先,让我们创建一个用户并授予他们对特定表的一些权限。

-- 步骤 1:为示例创建用户和数据库/表
CREATE DATABASE IF NOT EXISTS my_app_db;
CREATE TABLE IF NOT EXISTS my_app_db.products (id INT, name VARCHAR(100));
CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'password123';
-- 步骤 2:授予 SELECT 和 UPDATE 权限
GRANT SELECT, UPDATE ON my_app_db.products TO 'test_user'@'localhost';
-- 步骤 3:验证已授予的权限
SHOW GRANTS FOR 'test_user'@'localhost';

SHOW GRANTS 的输出将包含:GRANT SELECT, UPDATE ON my_app_db.productsTOtest_user@localhost`。

现在,让我们撤销 UPDATE 权限,但保留 SELECT 权限。

REVOKE UPDATE ON my_app_db.products FROM 'test_user'@'localhost';

一个 Query OK 响应表示成功。无需 FLUSH PRIVILEGES。

为确认权限已移除,我们再次检查授权。

SHOW GRANTS FOR 'test_user'@'localhost';

新的输出现在将只显示:GRANT SELECT ON my_app_db.productsTOtest_user@localhost`。

要移除用户的所有权限,您可以使用 REVOKE ALL PRIVILEGES。如果账户被停用,通常会接着 DROP USER。

-- 这将撤销授予用户的所有权限。
-- GRANT OPTION 允许用户将其自己的权限授予他人。
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'test_user'@'localhost';

运行此命令后,该用户的 SHOW GRANTS 将只显示 GRANT USAGE ON *.* ...,这意味着用户可以连接,但对任何数据库对象都没有权限。

角色是管理权限的强大功能。无需向用户授予许多单独的权限,您可以将权限授予角色,然后将角色授予用户。撤销角色就像撤销权限一样简单。

-- 步骤 1:创建角色并授予权限
CREATE ROLE 'read_only_role';
GRANT SELECT ON my_app_db.* TO 'read_only_role';
-- 步骤 2:将角色授予用户
CREATE USER 'analyst'@'localhost' IDENTIFIED BY 'analytics_pass';
GRANT 'read_only_role' TO 'analyst'@'localhost';
-- 步骤 3:现在,从用户撤销角色
REVOKE 'read_only_role' FROM 'analyst'@'localhost';

用户 ‘analyst’ 不再拥有 ‘read_only_role’ 提供的 SELECT 权限。

从应用程序中撤销权限时,请始终使用带参数化查询的 REVOKE 语句,以确保安全并防止错误。

示例(使用 mysql-connector-python 的 Python)

Section titled “示例(使用 mysql-connector-python 的 Python)”
import mysql.connector
def revoke_privileges(config, username, hostname, privilege, database):
try:
with mysql.connector.connect(**config) as connection:
with connection.cursor() as cursor:
# 使用 format 安全地构建 DCL 查询字符串
# 注意:DCL 语句通常不支持标识符的参数替换。
# 如果输入来自外部来源,请仔细清理。
query = f"REVOKE {privilege} ON `{database}`.* FROM %s@%s"
cursor.execute(query, (username, hostname))
connection.commit()
print(f"Successfully revoked {privilege} from '{username}'@'${hostname}' on database '{database}'.")
except mysql.connector.Error as err:
print(f"Error: {err}")
if __name__ == "__main__":
db_config = {
'host': 'localhost',
'user': 'root',
'password': 'your_root_password'
}
# 示例:从 my_app_db 数据库的 test_user 撤销 INSERT 权限
revoke_privileges(db_config, 'test_user', 'localhost', 'INSERT', 'my_app_db')