重置密码时 reset_password 路由无响应,主因是 authfilter 等中间件误拦截,需在 filters.php 的 except 列表中显式放行 'auth/forgot'、'auth/reset-password'、'auth/process-reset';同时排查邮件令牌生成与数据库字段类型(datetime)是否匹配、重置后是否清空 reset_token 和 reset_expires。

重置密码时 reset_password 路由没响应?检查路由是否被过滤器拦截
CodeIgniter 4 默认启用中间件(Middleware),reset_password 这类未登录态操作常被 AuthFilter 或自定义权限中间件误拦。现象是访问 /auth/reset-password 直接跳转登录页或报 403。
- 打开
app/Config/Filters.php,确认AuthFilter的except列表包含重置相关路径:['auth/forgot', 'auth/reset-password', 'auth/process-reset'] - 若使用了自定义中间件(如
RoleFilter),同样需在except中显式放行,否则即使用户未登录也会被拒 - 临时验证方式:在对应控制器方法开头加
log_message('debug', 'Reset route hit');,再查日志确认是否进到方法里
ForgotPasswordController::sendResetEmail() 发不出邮件?重点查 email 配置和令牌生成逻辑
重置流程卡在“发送邮件”环节,90% 是配置或令牌失效导致——不是 SMTP 设置错,而是 CodeIgniter 的 TokenGenerator 和邮件模板变量不匹配。
-
app/Config/Email.php中确保$protocol = 'smtp'且$SMTPUser已填;但更关键的是:重置链接中的token必须由\CodeIgniter\Security\TokenGenerator生成,并存入数据库(如users.reset_token字段) - 检查邮件模板(
Views/emails/reset_password.php)中是否用了base_url("auth/process-reset?token={$token}")—— 注意{$token}是原始字符串,不能是hash($token),否则校验失败 - 调试技巧:在发送前
var_dump($token, $user->reset_token);,确认两者一致;若不一致,说明saveToken()方法没执行或被覆盖
ProcessResetController::handle() 提示 “Invalid or expired token”?时间戳与数据库字段类型不匹配
用户点击邮件链接后报无效令牌,常见原因是 reset_expires 字段用 DATETIME 存储,但 PHP 生成的过期时间用了 time() + 3600(Unix 时间戳),类型错位导致 SQL 比较永远为假。
- 数据库中
reset_expires必须是DATETIME类型,则 PHP 端应生成格式化时间:date('Y-m-d H:i:s', time() + 3600),而非直接存整数 - 查询语句要同时校验状态与时间:
WHERE reset_token = ? AND reset_expires > NOW() AND active = 1;漏掉NOW()或写成> ?(传入 Unix 时间戳)都会失败 - 注意 MySQL 时区:若服务器时区是 UTC,而应用用
date_default_timezone_set('Asia/Shanghai'),会导致NOW()和 PHP 生成时间偏差 8 小时
重置成功后用户仍无法登录?别忘了清空 reset_token 和 reset_expires
密码改完了,但下次用新密码登还是失败——大概率是数据库里残留了旧 reset_token,某些登录逻辑会误判该用户处于“重置中”状态而拒绝认证。
- 在
ProcessResetController::handle()更新密码后,必须立即执行:$user->reset_token = null; $user->reset_expires = null; $this->userModel->save($user); - 不要依赖软删除或状态字段代替清空;有些项目加了
is_resetting布尔字段,但没在登录验证逻辑里检查它,等于白加 - 测试时用
php spark db:seed清库重试比反复手动删记录快,尤其当users表有外键约束时
重置密码功能最脆弱的环节不在加密算法,而在时间、类型、中间件这三处隐性耦合点。改一个地方,另外两个地方不动,就容易出现“看起来能跑,但总在某个环节静默失败”的情况。











