一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何强制MySQL用户首次登录修改密码

时间:2026-08-16 10:28:49 编辑:袖梨 来源:一聚教程网

必须用 ALTER USER ... PASSWORD EXPIRE,SET PASSWORD 无效且只对新登录生效;因 SET PASSWORD 仅更新 authentication_string 而不设置 password_expired 字段,而 MySQL 强制改密依赖 password_expired 元数据驱动。

必须用 ALTER USER ... PASSWORD EXPIRESET PASSWORD 无效,且只对新登录生效。

为什么 SET PASSWORD 不触发强制改密

SET PASSWORD FOR 'u'@'h' = 'xxx' 只更新 authentication_string 字段,完全不碰 password_expired。MySQL 的强制改密逻辑是元数据驱动的——只要 password_expired'N',哪怕密码刚设完,登录后照样能执行 SELECT

  1. 错误写法:SET PASSWORD FOR 'alice'@'localhost' = 'new123'; ALTER USER 'alice'@'localhost' PASSWORD EXPIRE; —— 两步分离,第二步容易漏
  2. 正确写法(一步到位):ALTER USER 'alice'@'localhost' IDENTIFIED BY 'new123' PASSWORD EXPIRE;
  3. 只想标记过期、不改密码:ALTER USER 'alice'@'localhost' PASSWORD EXPIRE;,别混用 IDENTIFIED BY

执行前必须检查三个前提

命令跑成功 ≠ 生效。以下任一不满足,PASSWORD EXPIRE 就是摆设:

  1. 用户必须已存在:SELECT user, host FROM mysql.user WHERE user = 'alice';
  2. 执行者要有 ALTER USER 权限(不是 UPDATE 权限)
  3. SELECT @@default_password_lifetime; 不能为 0;若为 0,全局禁用过期机制,所有 PASSWORD EXPIRE 都失效

用户登录后没报 ERROR 1820?查这三点

设了 PASSWORD EXPIRE 却还能正常执行 SELECT,大概率是:

  1. 服务器全局关闭了过期机制:SELECT @@default_password_lifetime; 返回 0
  2. 客户端连接后自动执行了 SET NAMES utf8mb4 等语句,但还没发第一条非 SET 类语句——ERROR 1820 要等到首个非 SET 语句才触发
  3. 用户已有活跃连接:过期策略只作用于新登录,已有连接不受影响

PASSWORD EXPIRE NOW 和 INTERVAL N DAY 的区别

两者都把 password_expired 设为 'Y',但后续行为不同:

  1. PASSWORD EXPIRE NOW:下次登录认证成功后,首次执行非 SET 语句就报错
  2. PASSWORD EXPIRE INTERVAL 60 DAY:从 password_last_changed 时间起算 60 天;若当前已超期,效果等同于 NOW
  3. 查是否真超期,不能只看 password_expired 字段:SELECT user, host, password_last_changed, TIMESTAMPADD(DAY, @@default_password_lifetime, password_last_changed) AS expires_at FROM mysql.user WHERE user = 'alice';

最容易被忽略的是:过期状态在服务端认证后、授权前就返回错误,根本不会走到 SQL 执行阶段——所以没法用 mysql -u alice -p 交互式输入绕过,也没法在连接池里“先连再处理”。

热门栏目