Laravel 8搭配Jetstream对接Gmail SMTP发信认证失败咨询
Laravel 8 配置Gmail发信实现角色变更通知方案
谷歌2022年已全面下线个人Gmail账号的「低安全性应用访问」入口,所有旧教程中靠开启该选项使用账号密码直连SMTP的方法已全部失效,遇到的535认证报错本质是使用普通登录密码连接SMTP被谷歌安全策略拦截。
方案一:应用专用密码方式(配置最简单,90%场景适用)
前置要求:Gmail账号必须开启两步验证,这是当前使用账号密码模式发信的唯一官方支持路径。
- 登录谷歌账号安全中心,找到两步验证设置页完成开启(绑定手机号或验证器均可)
- 两步验证开启后,安全页会显示「应用专用密码」入口,进入后选择应用类型为「其他/自定义」,自定义名称填
Laravel项目发信即可,点击生成后会得到一串16位无空格的密码,立刻复制保存,该密码关闭页面后无法再次查看 - 打开项目根目录
.env文件,修改邮件配置项如下:
MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=你的完整Gmail地址,例如xxx@gmail.com MAIL_PASSWORD=刚才生成的16位应用密码,直接粘贴不要加空格 MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=和上面MAIL_USERNAME一致的Gmail地址 MAIL_FROM_NAME="${APP_NAME}"
- 执行命令清除配置缓存:
php artisan config:clear,这步必须操作,Laravel配置缓存优先级高于.env文件,多数配置不生效问题都是没清缓存导致 - 本地测试可临时添加测试路由验证发信:
// 放到routes/web.php中,测试完成后立刻删除 Route::get('/mail-test', function () { Mail::raw('邮件测试内容', function ($message) { $message->to('你自己的收信邮箱')->subject('Laravel发信测试'); }); return '发信请求已发送'; });
访问对应路由如果能收到邮件,说明SMTP配置正常。
方案二:XOAUTH2认证方式(适合无法开启两步验证的场景)
如果是企业Gmail账号或无法开启两步验证,走OAuth2认证即可:
- 登录谷歌云控制台,新建项目后搜索启用Gmail API,进入凭据页创建OAuth2.0客户端ID,应用类型选Web应用,配置好授权重定向地址,创建完成后拿到客户端ID、客户端密钥
- 项目根目录执行命令安装谷歌邮件依赖:
composer require symfony/google-mailer - 修改
.env配置项:
MAIL_MAILER=smtp MAIL_DSN=gmail+xoauth2://你的Gmail地址:客户端ID:客户端密钥@default
- 第一次触发发信时会跳转到谷歌授权页,授权应用拥有Gmail发信权限后即可正常使用,不需要存储账号密码。
用户角色变更自动发信实现(适配Laravel 8 + Jetstream)
不需要修改Jetstream核心逻辑,按以下步骤实现即可:
- 生成通知类:执行
php artisan make:notification RoleChangedNotification,在生成的通知类里配置via方法返回['mail'],在toMail方法里写好邮件标题、内容,支持直接渲染Blade模板 - 创建用户模型观察者:执行
php artisan make:observer UserObserver --model=User,在观察者的updated方法里判断用户role字段是否发生变更,如果有变更,直接调用$user->notify(new RoleChangedNotification($user->role))触发通知 - 注册观察者:在
AppServiceProvider的boot方法里添加User::observe(UserObserver::class);即可 - 发信量大的场景建议把通知推队列执行,避免接口阻塞,Jetstream默认自带队列支持,只需要修改
.env里QUEUE_CONNECTION=database,执行php artisan queue:table && php artisan migrate生成队列表,启动队列进程即可。
常见报错排查
- 仍然报535用户名密码错误:先确认使用的是16位应用专用密码,不是Gmail账号的登录密码,检查密码有没有多余空格,确认加密方式是
tls、端口是587,不要混用加密方式和端口 - 连接SMTP超时:检查服务器/本地开发环境有没有开放587端口的出站权限,本地如果开了代理注意配置系统环境变量的代理规则,避免拦截SMTP请求
- 配置修改后无变化:必须执行
php artisan config:clear清除缓存,必要时可以执行php artisan cache:clear清理所有缓存。
内容的提问来源于stack exchange,提问作者Christopher Paz
相关产品推荐
相关产品推荐

