Laravel9 Symfony Mailer发信成功但Gmail收不到邮件排查
Laravel 9升级后cPanel主机提示发信成功但Gmail收不到验证邮件问题排查
问题现象
- Laravel 8版本可正常发送邮箱验证邮件,升级到Laravel 9后,页面提示邮件已发送,但Gmail邮箱实际未收到对应邮件
- 已核对域名服务商提供的邮件主机地址、端口、用户名、密码配置,与之前可用配置完全一致,尝试将加密方式从ssl修改为tls,问题未解决
- 本地环境连接mailtrap测试发信功能正常,项目部署到cPanel共享主机、按参数配置邮件信息后,注册流程返回符合代码逻辑的成功提示,但注册邮箱始终收不到激活邮件,已排查4天未定位原因
现有配置
.env文件配置
MAIL_MAILER=smtp MAIL_HOST=mail.getalow.com MAIL_PORT=465 MAIL_USERNAME=******** MAIL_PASSWORD=********* MAIL_ENCRYPTION=ssl MAIL_FROM_ADDRESS="support@getalow.com" MAIL_FROM_NAME="${APP_NAME}"
已在mail.php配置文件中添加'verify_peer' => false配置,未生效
mail.php配置
'smtp' => [ 'transport' => 'smtp', 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'port' => env('MAIL_PORT', 587), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, 'verify_peer' => false, // <------ IT HAS TO BE HERE ],
业务逻辑配置
- User模型已按规范实现
MustVerifyEmail接口,与之前可用配置一致:
class User extends Authenticatable implements MustVerifyEmail
- 注册控制器已正确添加
event(new Registered($user));逻辑触发验证邮件发送,对应RegistrationController.php代码:
// Register a new user public function register(RegistrationRequest $request) { $user = User::create($request->validated())->assignRole(['User', 'Commenter']);; event(new Registered($user)); Auth::login($user); return to_route('home') ->with(Helpers::Toast( 'Welcome ' . $user->name, 'Your account has been created.', 'success', '5000' )); }
排查与修复步骤
清理配置缓存
共享主机部署后若未清理配置缓存,修改的.env和mail.php配置不会生效。有SSH权限的话在项目根目录执行以下命令:php artisan config:clear php artisan cache:clear php artisan config:cache无SSH权限可通过cPanel文件管理进入
bootstrap/cache目录,删除所有config*.php格式的缓存文件即可。修正SMTP SSL验证配置(Laravel 9核心兼容问题)
Laravel 9将底层邮件组件从Swift Mailer替换为Symfony Mailer后,原有的verify_peer配置项直接写在smtp节点下不会生效,需要替换为完整的stream上下文配置,修改mail.php中smtp配置段如下:'smtp' => [ 'transport' => 'smtp', 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'port' => env('MAIL_PORT', 587), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, 'stream' => [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true, ], ], ],修改完成后再次清理配置缓存。
验证cPanel主机端口与邮件路由设置
绝大多数cPanel共享主机会默认封禁25、465等对外SMTP端口,避免垃圾邮件发送:- 进入cPanel「邮件路由」选项,确认使用主机自带邮件服务时,域名路由设置为「本地」
- 进入cPanel「电子邮件可送达性」功能,校验域名的SPF、DKIM解析记录,按照提示一键修复缺失、错误的解析项,避免Gmail将邮件判定为垃圾邮件直接拒收
- 联系主机商确认允许发信的SMTP端口,部分cPanel主机要求使用587端口配合tls加密发信,而非465端口ssl加密,可切换端口测试
通过服务器日志定位投递问题
进入cPanel「邮件跟踪」/「邮件投递报告」功能,直接查询服务器层面的发信日志,可直接定位问题:- 日志显示发信认证失败:重置邮箱密码后重新填入.env,注意cPanel自建邮箱的用户名需填写完整邮箱地址,而非@前缀的账号名
- 日志显示投递成功但Gmail收不到:检查邮件是否被归类到Gmail的垃圾邮件、推广邮件文件夹,同时确认域名没有被列入公开邮件黑名单
- 日志显示被服务器拦截:检查cPanel是否配置了发信频率、发信人身份限制,按提示放开对应权限即可
服务器连通性直连测试
在项目路由文件中添加临时测试路由,跳过注册流程直接调用Mail类发信,可直接输出具体报错:Route::get('/test-mail', function () { try { \Mail::raw('服务器发信测试内容', function($msg) { $msg->to('你的测试Gmail地址')->subject('发信连通性测试'); }); return '发信指令执行成功,请查收邮箱'; } catch (\Exception $e) { return '发信报错:' . $e->getMessage(); } });访问该路由即可看到具体的连接、认证报错,无需反复走注册流程测试,测试完成后删除该路由即可。
内容的提问来源于stack exchange,提问作者Code Flow
相关产品推荐
相关产品推荐

