Laravel 发送邮件
标签:
编程学习
PHP学习
给博客添加邮件系统,博主太穷,没有使用三方的邮件推送服务,直接使用的阿里云企业邮箱 SMTP 发信,其实与腾讯、网易的 SMTP 发送邮件是一样的,就是登陆你的账户进行发送。
前置条件
首先需要有个备案域名,注册阿里、网易或者腾讯的企业邮箱(QQ个人邮箱也可以发,我选企业邮箱~.~),然后自行添加域名 MX 解析,直到生效,后面就是添加发信邮箱账号并配置密码,这里要注意一下,添加账号的时候要勾选SMTP和POP3,当然添加后设置也行
最后需要获取一下发件端口,我这里用的阿里云,下面贴出介绍地址
http://mailhelp.mxhichina.com/smartmail/detail.vm?knoId=5871700
这里不建议用 25 端口,因为阿里云服务器为了安全,关闭了 25 端口,想开启需要申请,挺麻烦。
配置发件信息
在 .env 文件中添加邮箱发件配置
MAIL_DRIVER=smtp
# 网易:smtp.ym.163.com;阿里:smtp.qiye.aliyun.com
MAIL_HOST=smtp.qiye.aliyun.com
# 发件端口,网易:994;阿里:465
MAIL_PORT=465
# 发件人邮箱帐号
MAIL_USERNAME=
# 发件人邮箱密码
MAIL_PASSWORD=
# 加密方式,因为 SMTP 没有使用 25 端口,所以此处填写 ssl
MAIL_ENCRYPTION=ssl
# 配置全局默认发件地址
MAIL_FROM_ADDRESS=
# 发件人名称
MAIL_FROM_NAME=
添加依赖函数库
这个服务基于 API 的驱动,所有的 API 驱动都需要 Guzzle HTTP 函数库,需要使用 Composer 包管理器安装它
composer require guzzlehttp/guzzle
创建邮件管理类及内容视图
php artisan make:mail RegisterMail --markdown=email.register
该命令会直接创建邮件管理文件 app/Mail/RegisterMail.php
class RegisterMail extends Mailable {
use Queueable, SerializesModels;
private $code;
private $title;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($title, $code)
{
$this->code = $code;
$this->title = $title;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('email.register', ['code'=>$this->code])->subject($this->title);
}
}
视图文件resources/views/email/register.blade.php
@component('mail::message')
### 欢迎注册 Duicode 账号,您的邀请码是:
<br/>
# {{ $code }}
<br/>
##### 验证码有效期为 15 分钟, 请及时使用。
Thanks,<br>
{{ config('app.name') }}
@endcomponent
如果想修改 component 包含的文件内容,可以执行下面命令导出文件进行编辑,执行该命令后 resouces/views 下会多出 vendor/mail 目录
php artisan vendor:publish --tag=laravel-mail
测试发件
添加路由
Route::get('sendEmailCode', 'AuthController@sendCodeAction');
添加发件方法
public function sendCodeAction(Request $request) {
//获取提交过来的邮箱
$email = $request->get('email');
if (empty(trim($email))) return ApiResponseBuilder::errorWithMessage(200,'请输入邮箱',200);
//生成随机的四位数验证码
$code = mt_rand(1000, 9999);
//主要是这一句
$result = Mail::to($email)->send(new RegisterMail('注册验证码', $code));
if($result == null){
//验证码存入缓存 有效期15分钟
\Cache::put("email_code" . $email, $code, Carbon::now()->addMinute(15));
$data = "验证码发送成功 ---" . $code;
return ApiResponseBuilder::success($data);
} else {
return ApiResponseBuilder::errorWithMessage(200,'验证码失败',200);;
}
}
防爆接口
为了防止接口被刷,我这里添加了云片行为验证(普通用户免费~.~),需要注册云片账号并进行实名认证,首先在前端添加验证码,在请求接口的时候添加云片验证后的token和authenticate,后端在发送邮件之前添加二次验证
public function sendCodeAction(Request $request) {
//获取提交过来的邮箱
$email = $request->get('email');
if (empty(trim($email))) return ApiResponseBuilder::errorWithMessage(200,'请输入邮箱',200);
// 获取云片验证数据
$token = $request->get('token');
$authenticate = $request->get('authenticate');
if (empty(trim($token)) || empty(trim($authenticate))) return ApiResponseBuilder::errorWithMessage(200,'验证失败',200);
// 云片二次验证
$params = array();
$params["authenticate"] =$authenticate; //用户验证通过后,返回的参数
$params["token"] =$token; //前端返回的 token
$params["captchaId"] =''; //验证应用 id
$params["secretId"] =''; //验证应用 secretId
$secretKey = ''; //验证应用 secretKey
$params["version"] = "1.0"; //版本,固定值1.0
$params["timestamp"] = sprintf("%d", round(microtime(true)*1000)); // 当前时间戳的毫秒值,如1541064141441
$params["nonce"] = sprintf("%d", rand(1,99999)); //随机正整数, 在 1-99999 之间
ksort($params); // 参数排序
$buff="";
foreach($params as $key=>$value){
$buff .=$key;
$buff .=$value;
}
$buff .= $secretKey;
//print_r($buff);
$signature=md5($buff);
$params["signature"] =$signature ; //签名信息,见签名计算方法
$url="https://captcha.yunpian.com/v1/api/authenticate";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
/* 设置返回结果为流 */
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
/* 设置超时时间*/
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
/* 设置通信方式 */
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
$result = curl_exec($ch);
if ($result['code'] != 0) {
return ApiResponseBuilder::errorWithMessage(200, $result['msg'],200);
}
//生成随机的四位数验证码
$code = mt_rand(1000, 9999);
//主要是这一句
$result = Mail::to($email)->send(new RegisterMail('注册验证码', $code));
if($result == null){
//验证码存入缓存 有效期5分钟
\Cache::put("email_code" . $email, $code, Carbon::now()->addMinute(5));
$data = "验证码发送成功 ---" . $code;
return ApiResponseBuilder::success($data);
} else {
return ApiResponseBuilder::errorWithMessage(200,'验证码失败',200);;
}
}
这就是目前搞的发送邮件流程了。