分享到

简介

用户管理是任何希望管理 MySQL 数据库系统的人最重要的职责之一。创建、更改和删除用户帐户,以最好地表示您环境中的用户和服务,这有助于为锁定访问、限制更改范围以及实施修改的审计和问责制奠定基础。

在本指南中,我们将讨论如何在 MySQL 中管理用户帐户。首先,我们将讨论 MySQL 中有效用户的定义,并向您展示如何向系统添加其他用户。这将引出关于如何为每个用户配置身份验证以及系统如何从一系列可能性中选择身份验证选项的讨论。我们将继续讨论如何更改现有用户、如何使用您创建的帐户登录以及如何删除您不再需要的用户。

先决条件

要遵循本指南,您需要一个具有适当权限的 MySQL 服务器帐户。

我们将使用的命令

要在 MySQL 中创建、修改和删除用户,您需要的核心命令是

  • CREATE USER:创建新用户帐户
  • ALTER USER:更改现有用户帐户
  • DROP USER:删除现有用户帐户

所需权限

要执行上述命令,您需要使用具有 CREATE USER 权限的帐户登录 MySQL。CREATE USER 权限允许您创建、修改、删除和重命名用户以及其他操作。我们还需要 SELECT 权限才能在 mysql 数据库上查看有关现有用户的信息。

按优先级顺序,您应该使用以下帐户登录

  • 具有 CREATE USER 权限和 mysql 数据库上的 SELECT 权限的受限帐户
  • 在 MySQL 中具有完全权限的 root 或管理用户

了解 MySQL 如何定义和解释用户帐户

在我们开始创建新帐户之前,花一些时间熟悉 MySQL 用于创建和引用用户的各种方式是很有帮助的。您还需要熟悉 MySQL 的身份验证算法,以了解它将使用哪个用户帐户来验证连接。

MySQL 的用户帐户语法是什么?

在 MySQL 中,用户帐户由两个独立的信息片段组成,用 at 符号 (@) 连接

  • 用户名
  • 用户连接的主机

一般来说,系统上的用户帐户将如下所示

'<user>'@'<host>'

可以使用单引号(如上所示)分别包装用户帐户的用户和主机组件。如果任何一个组件包含会被误解的字符,则有时是必要的。一般来说,始终添加它们是一个明确的好主意。

因此,在 MySQL 中,与其仅仅拥有一个名为 'john' 的帐户,完整的帐户名将需要某种主机,例如 'john'@'localhost'。这意味着系统上可能存在多个 'john' 帐户,只要它们来自不同的域,MySQL 就会将它们都视为唯一帐户。

话虽如此,可以定义没有用户或主机组件的用户帐户,但是您必须意识到重要的含义。

您可以使用空字符串定义没有用户值的用户帐户

''@'<host>'

例如,您可以将用户创建为 ''@'localhost'。此用户将匹配从本地计算机连接的任何用户名。

同样,您可以拥有一个匹配任何主机的用户帐户。与其使用空字符串,对于主机值,您将使用 % 通配符,如下所示

'<user>'@'%'

例如,如果您创建 'john'@'%',则该帐户将匹配从任何主机连接的 'john' 用户。

MySQL 如何验证用户身份?

了解 MySQL 实际上如何处理每个身份验证请求非常重要,以避免因合理但不正确的假设而导致的一类常见的身份验证问题。这在我们关于 MySQL 中身份验证和授权简介文章中进行了一些深入讨论。

在验证连接请求时,MySQL 使用其内部 mysql 数据库的 user 表中的多个字段来决定是否允许连接。MySQL 将最多使用一个用户帐户记录来尝试验证连接。这意味着,如果存在多个可以匹配连接的帐户,MySQL 需要一种方法来决定使用哪个用户帐户。

MySQL 的用户身份验证算法在服务器启动时开始。在启动时,MySQL 将整个 mysql.user 表加载到内存中。每当使用常规 MySQL 命令创建用户帐户时,它也会执行此操作。在加载表时,它会按优先级从高到低对条目进行排序。

MySQL 使用 Host 列作为主排序字段,并优先考虑具有更具体值的结果。因此,文字值被排序到顶部作为最高优先级,而使用通配符(如 %)的值被排序到底部。最后的条目是那些仅包含 % 而没有其他字符的条目,其次是具有完全空白主机的条目。

User 列用作具有相同 Host 值的任何条目的辅助排序字段。再次,更精确的匹配会被优先考虑。由于 User 列不能使用通配符,因此除了具有空白 User 值的条目之外,所有条目都处于同等地位。这些条目被排序到底部。如果选择了任何具有空白 User 值的条目,则用户将被验证为“匿名用户”,这通常等同于没有权限。

现在,每当发出连接请求时,MySQL 都会从上到下遍历其内存中已排序的表。它使用找到的第一个条目来验证用户身份,无论是否还有其他条目也匹配。如果客户端使用该条目定义的方法验证失败,则连接将失败,并且不会检查其他条目。

在 MySQL 用户帐户定义中不包含用户或主机有什么影响?

由于 MySQL 的身份验证算法,如果您在创建没有用户或主机组件的用户帐户时不够小心,可能会出现问题。这是因为 MySQL 决定使用哪个记录来验证您的身份的方式可能不直观且令人惊讶。

例如,如果用户使用空白字符串作为用户部分进行身份验证,则 MySQL 会将他们视为会话其余部分的“匿名用户”。通常,匿名用户几乎没有任何权力,并且一旦连接就几乎无法执行任何操作。甚至可能在尝试使用其他用户帐户进行身份验证时意外地以匿名用户身份进行身份验证。

为用户帐户使用通配符主机的挑战在于,包含主机值的其他用户帐户可以轻松地掩盖或使使用通配符的用户帐户不可用。

例如,如果您有一个定义为 'emily'@'%' 的用户帐户,您可能希望能够从任何主机验证到 'emily'。但是,如果您有一个用户帐户,其用户为空白,但主机值与 'emily' 连接的主机匹配,则 MySQL 将改为使用该帐户进行身份验证(导致如上所述的匿名用户登录)。

因此,例如,MySQL 将以下帐户按以下顺序排序

优先级MySQL 帐户评论
1'emily'@'localhost''emily'@'example.com'这些具有相同的优先级,这没问题,因为它们中只有一个可能匹配连接。
2''@'localhost'''@'example.com'这两个条目再次具有相同的优先级。由于它们没有用户组件,但它们确实具有文字主机组件,因此它们位于具有精确主机值的条目的底部。
3'emily'@'%.example.com'此条目在主机组件中具有通配符,因此其优先级低于具有精确主机值的条目。
4''@'%.example.com'此条目与主机值中具有通配符的条目分组在一起。由于它没有用户组件,因此位于此组的底部。
5'emily'@'%'此条目的主机值仅由通配符组成。由于它匹配任何主机,因此优先级非常低。
7''@'%'此条目可用于将来自任何主机的任何用户验证为匿名用户。它的优先级非常低,因为它匹配任何连接。
6'emily'@''此条目具有完全空白的主机值,其优先级甚至低于仅包含通配符主机的主机。
8''@''这是优先级最低的用户。它不包含任何主机信息,因此在主机排序期间将其放在末尾。由于它还包含一个空白用户,因此它位于此组中其他条目的下方。与所有没有用户的条目一样,使用此条目验证的连接将以匿名用户身份登录。

如何创建用户?

现在您对 MySQL 处理用户帐户的方式有所了解,我们可以开始创建一些新用户了。请记住使用先决条件中描述的权限的用户登录。

基本语法

创建新用户的基本语法相对简单。您使用 CREATE USER 命令,然后为新帐户指定用户和主机

CREATE USER '<user>'@'<host>';

这将创建一个基本帐户,而无需在创建时配置用户和主机之外的任何详细信息。

如何创建带密码的用户?

通常,您希望在创建用户时配置身份验证。您可以通过将可选的 IDENTIFIED BY 子句添加到 CREATE USER 语句来实现

CREATE USER '<user>'@'<host>' IDENTIFED BY '<password>';

这会创建一个新的用户帐户,与之前一样,并同时为该帐户分配密码。稍后我们将介绍如何在事后分配密码或如何更改用户的密码。

如何创建使用 Unix 套接字身份验证的用户?

虽然密码身份验证是大多数用户最常见的身份验证方法,但它不是唯一的选择。MySQL 提供了许多不同的内部和外部身份验证机制,您可以配置您的用户帐户以使用这些机制。例如,我们将使用 Unix 套接字身份验证配置一个新帐户。

Unix 套接字身份验证可以在 Linux 或类 Unix 环境中使用,以便操作系统上的帐户被授予对 MySQL 中相同帐户名的访问权限,而无需进一步身份验证。在这种配置中,MySQL 管理员知道操作系统上的用户帐户受到严格控制。

因此,如果操作系统上有一个 mary 用户,如果 Unix 套接字身份验证是定义的身份验证机制,他们将能够登录到 MySQL 中的 'mary'@'localhost' 帐户。让我们立即配置它。

套接字身份验证需要 auth_socket 插件,因此首先通过键入以下内容加载插件

INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';

接下来,创建一个用户帐户,该帐户与您在操作系统上拥有的用户帐户匹配。对于此示例,我们将使用上面讨论的 mary 帐户。如果您不使用与您的操作系统名称之一匹配的名称,您将无法使用此用户进行身份验证。

要使用套接字身份验证创建用户,我们需要使用 IDENTIFIED WITH 子句(与之前使用的 IDENTIFIED BY 子句不同)来指定要使用的身份验证插件

CREATE USER 'mary'@'localhost' IDENTIFIED WITH auth_socket;

现在,您应该能够从操作系统上的 mary 用户验证到 'mary'@'localhost' MySQL 用户。以 mary 身份登录后,连接到数据库,无需提供任何用户名或密码

mysql

您应该通过您配置的 Unix 套接字身份验证自动登录。

如何显示现有用户?

接下来,让我们看一下如何查找有关现有用户的信息。

要显示所有现有 MySQL 用户(包括其用户和主机组件)以及他们当前使用的身份验证插件,您可以从 mysql.user 数据库 SELECT 这些字段

SELECT user,host,plugin FROM mysql.user
+------------------+-----------+-----------------------+
user | host | plugin |
+------------------+-----------+-----------------------+
mary | localhost | auth_socket |
mysql.infoschema | localhost | caching_sha2_password |
mysql.session | localhost | caching_sha2_password |
mysql.sys | localhost | caching_sha2_password |
root | localhost | caching_sha2_password |
useradmin | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
6 rows in set (0.00 sec)

在这里,我们可以看到系统上定义了六个用户,所有用户都只能在本地登录。五个帐户配置为使用密码身份验证。'mary'@'localhost' 帐户配置为使用 Unix 套接字身份验证。

我们可以使用 SHOW CREATE USER 命令查找有关用户属性的其他信息。尽管名称如此,但它显示用户帐户的所有当前属性,而不一定是初始帐户创建期间使用的属性。

SHOW CREATE USER 命令将帐户名称作为参数

SHOW CREATE USER '<user>'@'<host>'\G

通常最好使用 \G 语句终止符而不是常用的冒号 (;) 结束命令,以便您可以更清楚地查看结果。

要显示 'useradmin'@'localhost' 帐户的属性,您将键入

SHOW CREATE USER 'useradmin'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for useradmin@localhost: CREATE USER 'useradmin'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$O
Rl7lM;@Gt{roB4EWchqDdYM142Lq7pfzcCNiK4yUxnRBlrAgr0sE3' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
1 row in set (0.00 sec)

如何更改现有 MySQL 用户?

您可以使用 ALTER USER 命令在 MySQL 中更改现有用户。这可用于更改帐户的大多数用户相关属性,但帐户权限除外,帐户权限由 GRANTREVOKE 命令控制。

ALTER USER 的基本语法如下所示

ALTER USER <user> <properties_to_change>;

如何更改 MySQL 用户的密码?

对于大多数人来说,ALTER USER 最常见的用途是修改密码。

例如,您可以通过键入以下内容来修改 'kamal'@'localhost' 的密码

ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>';

如果您想为用户设置一个临时密码,他们必须立即替换该密码,您可以同时设置和过期密码

ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>' PASSWORD EXPIRE;

即使没有 CREATE USER 权限,您也始终可以更改自己的密码。 最简单的方法是使用 USER() 函数自动填写您自己的用户名

ALTER USER USER() IDENTIFIED BY '<new_password>';

如何更改 MySQL 用户的身份验证插件?

您还可以更改用于验证帐户的机制或插件。

在之前的示例中,我们配置了一个名为 'mary'@'localhost' 的帐户以使用 Unix 套接字身份验证。 如果我们稍后想将该帐户更改为使用传统的密码身份验证,我们可以再次使用 ALTER USER 命令。

首先,确定服务器的默认身份验证插件。 如果它是基于密码的身份验证方法,则最好重用默认选择

SHOW VARIABLES LIKE 'default_authentication_plugin';

在本例中,默认的身份验证插件是 caching_sha2_password,因此当切换到密码身份验证时,我们将使用它。

现在,将 'mary'@'localhost' 更改为使用 caching_sha2_password 插件并设置新密码

ALTER USER 'mary'@'localhost' IDENTIFIED WITH 'caching_sha2_password' BY '<marys_password>';

'mary'@'localhost' 用户将无法再使用 Unix 套接字身份验证登录,但他们可以使用提供的密码登录。

如何登录 MySQL?

我们已经讨论了如何创建和修改 MySQL 用户帐户,包括身份验证。 但是,我们还没有讨论如何使用这些身份验证方法实际登录。

mysql 客户端是一个强大的命令行客户端,可用于连接到本地和远程数据库。 我们将使用它来讨论如何使用上面配置的方法进行身份验证。

如何使用密码登录本地数据库?

要使用带有密码的用户帐户登录到本地托管的 MySQL 数据库,基本语法如下所示

mysql --user=<username> --password <dbname>

因此,如果 'kamal'@'localhost' 用户想要登录 MySQL 并从系统托管的计算机连接到 testing 数据库,他们可以键入

mysql --user=kamal --password testing

mysql 客户端将提示输入 'kamal'@'localhost' 的密码。 如果您提供正确的凭据,您将连接到 testing 数据库。

在命令行上指定数据库是可选的。 如果未指定任何数据库,您将连接到服务器,但不会连接到特定的数据库。

如何使用 Unix 套接字身份验证登录本地数据库?

要使用 Unix 套接字身份验证登录到本地 MySQL 服务器,您需要以匹配的帐户名登录到您的操作系统。 因此,如果我们想使用 Unix 套接字身份验证来验证 'mary'@'localhost',我们首先必须使用名为 mary 的用户名登录到我们的计算机。

一旦您使用正确的操作系统帐户,您就可以通过执行客户端直接连接到本地数据库,无需任何选项。

mysql

和之前一样,您可以选择附加数据库名称以连接到您想要的特定数据库。

如何使用密码登录远程数据库?

如果您的 MySQL 服务器未在本地服务器上运行,则您必须指定客户端应尝试连接的主机。 您可以通过添加 --host 选项来执行此操作。

大多数情况下,您将使用密码验证远程 MySQL 服务器,因此命令如下所示

mysql --user=<username> --password --host=<host> <dbname>

因此,'tanya'@'<tanyas_domain>' 可以通过键入以下内容连接到位于 example.com 上的 MySQL 服务器

mysql --user='tanya' --password --host='example.com'

如何删除 MySQL 用户?

保留不再有用的用户帐户是一种安全风险。 您可以使用 DROP USER 命令轻松删除帐户。

基本语法如下所示

DROP USER '<user>'@'<host>';

因此,要删除 'mary'@'localhost' 用户,您需要键入

DROP USER 'mary'@'localhost';

如果您尝试删除不存在的用户,您将收到错误

ERROR 1396 (HY000): Operation DROP USER failed for 'mary'@'localhost'

为避免这种情况,您可以在帐户名称前添加 IF EXISTS 子句。 如果用户存在,它将被删除。 如果不存在,则只会发出警告

Query OK, 0 rows affected, 1 warning (0.00 sec)

结论

MySQL 的用户帐户管理和身份验证配置非常灵活。 了解如何在 MySQL 中创建、修改和获取有关用户的信息将帮助您更有效地管理数据库系统。

安全最佳实践规定,您应该为每个独特的用例创建帐户,仅授予执行其范围所需的访问级别。 帐户创建和身份验证是此过程的第一阶段。 在另一份指南中,我们将讨论如何授予和撤销权限以实现该策略的另一部分。

常见问题解答

更改用户密码最常见的方法是使用 ALTER USER。 例如,您可以使用以下命令修改 'kamal'@'localhost' 的密码

ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>';

您还可以通过使用以下命令设置临时密码

ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>' PASSWORD EXPIRE;

当尝试以 root 用户身份登录到 MySQL 数据库时,您可能会收到错误,这可能有多种潜在原因。 MySQL 在其文档中解决了您可以执行的故障排除检查

一些常见情况包括需要重置 root 用户密码或编辑配置文件

您可以使用 DROP USER 命令在 MySQL 中删除用户。 基本语法如下所示

DROP USER '<user>'@'<host>';

为避免尝试删除不存在的用户,您可以在帐户名称前包含 IF EXISTS 子句。

要列出 MySQL 实例中的所有用户,您可以使用 SELECT 语句在 mysql.user 数据库上进行查询。 当同时包含 hostplugin 时,语法如下所示

SELECT user,host,plugin FROM mysql.user;

要显示当前用户的授权,您可以使用以下语法

SHOW GRANTS;

对于其他用户,您可以使用

SHOW GRANTS FOR '<user>'@'<host>';
关于作者
Justin Ellingwood

Justin Ellingwood

自 2013 年以来,Justin 一直在撰写关于数据库、Linux、基础设施和开发者工具的文章。 他目前与妻子和两只兔子住在柏林。 他通常不必以第三人称写作,这对所有相关方来说都是一种解脱。