Laravel邮箱验证链接有效期默认60分钟,由SendEmailVerificationNotification类硬编码控制,需通过自定义通知类重写toMail()方法并修改URL::temporarySignedRoute的$expires参数来安全调整。

默认的邮箱验证链接有效期是 60 分钟,但这个值不能直接改配置文件生效,必须通过重写 SendEmailVerificationNotification 类或自定义通知类来调整。
验证链接过期时间在哪控制
Laravel 的邮箱验证链接由 URL::temporarySignedRoute 生成,其有效期由传入的 $expires 参数决定。框架内置的 SendEmailVerificationNotification 类硬编码了 60 分钟(now()->addMinutes(60)),不提供配置项暴露给 .env 或配置文件。
- 查看源码可确认:该类位于
vendor/laravel/framework/src/Illuminate/Auth/Notifications/SendEmailVerificationNotification.php - 它调用的是
URL::temporarySignedRoute('verification.verify', now()->addMinutes(60), [...]) - 所以哪怕你改了
config/auth.php里的其他设置,也不会影响这个时间
如何安全地修改有效期
推荐做法是创建一个自定义通知类继承原类,并覆盖 toMail() 方法中生成 URL 的逻辑。不要直接修改 vendor 文件,否则升级会丢失改动。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 运行
php artisan make:notification CustomEmailVerificationNotification - 在新类中复写
toMail(),用URL::temporarySignedRoute(..., now()->addMinutes(30), ...)替换掉 60 分钟 - 在
User模型中重写sendEmailVerificationNotification()方法,改为调用你的新通知类 - 确保该方法签名与父类一致:
public function sendEmailVerificationNotification()
为什么不能只改路由中间件或验证逻辑
signed 中间件本身不控制有效期,它只校验签名和时间戳是否匹配;真正决定“过期”的是生成 URL 时传入的 $expires 值。一旦 URL 被生成,它的 expires 参数就固定了,后端验证时只是比对当前时间是否小于该值。
- 手动调用
$request->hasValidSignature()也依赖这个原始时间戳,无法动态延长 - 试图在中间件里拦截并修改
expires参数无效,因为签名已绑定原始值 - 强行拼接或篡改 URL 中的
expires或signature会导致InvalidSignatureException
容易忽略的关键点
服务器时间不准、APP_KEY 变更、或用户本地时区与服务端差异过大,都可能导致链接提前失效或误判有效。尤其在跨时区部署时,now() 是基于 PHP 默认时区(非 UTC)计算的,如果未统一设为 date_default_timezone_set('UTC'),可能引发验证失败。
- 务必检查
config/app.php中的'timezone' => 'UTC'是否启用 - 生产环境建议用 NTP 同步服务器时间,避免因系统时间漂移导致大量链接“假过期”
- 不要在验证链接里传递敏感字段(如密码、token),签名 URL 不等于加密,仅防篡改

















