mysql - MySQL/MariaDB:“GRANT ... IDENTIFIED BY”与“CREATE USER”然后“GRANT”有什么区别?
问题描述
设置数据库时,我通常创建一个用户:
CREATE USER myuser@localhost IDENTIFIED BY 'pa$$w0rd';
然后给用户一些对数据库的权限:
GRANT SELECT, INSERT, UPDATE ON dbname.* TO 'myuser'@'localhost' IDENTIFIED BY 'pa$$w0rd';
我到处都看到这两个命令序列作为执行此操作的方法。但是,我注意到如果我跳过CREATE USER
命令并从GRANT
用户开始似乎是自动创建的并且工作正常。是否有理由CREATE USER
仍然应该使用之前GRANT
?或者它只是一个旧的约定,可能是为了向后兼容?
解决方案
MySQL过去仅通过授予用户权限来支持隐式创建用户。这种用法允许 GRANT 是幂等的和复制安全的。例如,当用户可能存在也可能不存在于副本上时,如果用户不存在,则 GRANT 将创建该用户。如果用户确实存在,那么 GRANT 仍然有效,并在需要时添加权限。
当以这种方式使用 GRANT 时,可以选择使用 IDENTIFIED BY 子句来设置密码。如果用户已经存在,则不需要 IDENTIFIED BY,因为用户已经有密码。如果用户不存在,那么省略 IDENTIFIED BY 将隐式创建用户,但没有密码(即任何人都可以在不输入密码的情况下以该用户身份登录)。
这被认为是一种安全风险。例如,如果有人在没有 IDENTIFIED BY 的情况下使用 GRANT,并且在用户名上出现拼写错误,则可能会意外创建一个具有权限但没有密码的新用户。
GRANT ALL ON *.* TO 'ruhnett'@'%'; -- misspelled username creates new user
这将允许任何人以新用户身份登录并获得特权访问。
所以在 MySQL 5.7 中,不推荐使用 GRANT 来隐式创建用户。
CREATE USER ... IF NOT EXISTS 语法取代了幂等用户创建。这鼓励开发人员更明确地确定何时要创建用户以及何时要向现有用户授予权限。
推荐阅读
- java - 拆分合并源java流的几个map
- docker - 基于 pytorch 的 Flask 应用程序映像在运行后退出
- julia - Julia 中的数组/列表操作
- azure - 有没有办法在 GUI 级别捕获 WAF 策略更改,然后使用它来触发 azure 管道?
- python - 烧瓶创建具有基于列值的链接的表
- mysql - Liquibase AWS Aurora (MYSQL) 架构更新:字段值变化对执行时间有影响吗?
- c# - 有没有更好的方法来构建与同一实体的多个一对一关系?
- r - 如何创建列值为 TRUE 的列名的列表列
- flutter - Sqflite颤振与主隔离通信
- r - 在 R 中用数百万行数据估算 NA