分享到

简介

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

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

前提条件

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

我们将使用的命令

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

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

所需权限

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

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

  • mysql 数据库上具有 CREATE USER 权限和 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,则 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、基础设施和开发者工具的文章。他目前与妻子和两只兔子住在柏林。他通常不必以第三人称写作,这对所有相关方来说都是一种解脱。