Yii2配置SMTP发送密码重置邮件失败 表单报错求助
Yii2忘记密码邮件功能报错排查
问题背景
需要实现忘记密码流程:用户提交注册邮箱后,系统向该邮箱发送重置密码链接,用户点击链接即可跳转设置新密码。目前参考官方文档完成了基础配置,但提交表单时控制台报ActiveForm相关错误,无法定位问题根源。
现有配置与代码
mailer组件配置
'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', 'htmlLayout' => '@app/mail/layouts/html', // 'viewPath' => '@common/mail', // 'useFileTransport' => true, 'transport' => [ 'class' => 'Swift_SmtpTransport', 'host' => 'smtp.gmail.com', 'username' => 'username', 'password' => 'app_password', 'port' => '587', 'encryption' => 'ssl', ], 'streamOptions' => [ 'ssl' => [ 'allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false, ], ], ]
控制器actionForgot代码
public function actionForgot() { if(isset($_POST['Lupa'])) { $getEmail=$_POST['Lupa']['email']; $getModel= Users::findOne(['email' => $getEmail]); $getToken=rand(0, 99999); $getTime=date("H:i:s"); // $getModel->token=md5($getToken.$getTime); $org="Some Team"; $emailadmin="admin_email"; $subjek="Reset Password"; $setpesan="you have successfully reset your password<br/> <a href='http://localhost:8080/site/forgot?r=site/vertoken/view&token='>Click Here to Reset Password</a>"; if(!$getModel) { Yii::$app->session->setFlash('error', 'Please fill in an registered email'); } else if($getModel->validate()) { $name='=?UTF-8?B?'.base64_encode($org).'?='; $subject='=?UTF-8?B?'.base64_encode($subjek).'?='; $headers="From: $name <{$emailadmin}>\r\n". "Reply-To: {$model->email}\r\n". "MIME-Version: 1.0\r\n". "Content-type: text/html; charset=UTF-8"; $getModel->save(); Yii::app()->user->setFlash('forgot','link to reset your password has been sent to your email'); mail($getEmail,$subject,$setpesan,$headers); Yii::$app->mailer->compose() ->setFrom($emailadmin) ->setTo($getEmail) ->setSubject($subjek) ->send(); $this->refresh(); } } $this->layout = 'forgot'; return $this->render('forgot'); }
触发报错的视图代码
<?php $form = ActiveForm::begin([ 'id' => 'forgot-form', 'enableClientValidation'=>false, 'validateOnSubmit' => true, ]); ?>
问题根因
控制台报ActiveForm相关错误是表象,本质是后端PHP代码运行抛出致命错误,导致AJAX验证请求返回500状态码,前端JS无法解析返回结果才报错,具体代码问题如下:
- SMTP配置错误:Gmail SMTP的587端口对应加密协议为
tls,465端口才对应ssl,当前配置端口和加密协议不匹配,会直接导致SMTP连接失败。另外streamOptions配置位置错误,该参数需要放在transport节点下,和host、port等参数同级,当前放在外层不会生效。同时配置中没有明确设置useFileTransport => false,部分环境下默认会开启写文件模式,不会真实发信。 - 混用Yii1和Yii2语法:
Yii::app()->user->setFlash()是Yii1框架的写法,Yii2中全局实例统一通过Yii::$app调用,运行到该行会直接抛出类不存在的致命错误。 - 未定义变量:组装邮件头时调用了
$model->email,但上下文中查询得到的用户对象变量名为$getModel,不存在$model变量,会触发未定义变量错误。 - 重复发信逻辑:同时调用了PHP原生
mail()函数和Yii mailer组件的send()方法,两套逻辑冗余,且原生mail()函数未配置SMTP的情况下无法正常发信,会额外抛出错误。 - 业务逻辑缺失:生成的重置密码token被注释,没有赋值给用户模型存储,邮件内的重置链接也没有拼接token参数,就算邮件发送成功,用户也无法完成密码重置。同时调用
$getModel->save()时没有判断返回值,模型保存失败时仍会继续执行后续发信逻辑。 - 邮件内容为空:调用
compose()方法时没有传入邮件视图或正文内容,提前写好的$setpesan正文没有被传入,最终发出的邮件是空白内容。 - 请求参数获取不规范:直接读取
$_POST['Lupa']获取表单参数,没有通过Yii提供的Yii::$app->request->post()方法获取,也没有绑定对应表单模型,参数名不匹配时会直接进入不了提交逻辑。
内容的提问来源于stack exchange,提问作者Paul Stokvinsky
相关产品推荐
相关产品推荐

