使用element表单组件配合nodemailer和koa实现以下效果:
-
邮件发送
系统会向指定邮箱发送一封包含验证码的邮件
-
验证码判别
打开邮箱,生成一封具有图片、验证码和用户名称的邮件,且验证码仅有10分钟有效期
首先验证element的ruleForm组件中name和email值全部有效,这里使用Promise.all方法来为异步函数执行加速。
//check the name and email must has value
let validateArray = ['name', 'email'];
let error = false;
await Promise.all(
validateArray.map(item => {
return this.$refs.ruleForm.validateField(item, Error => {
if (Error) error = true;
});
})
);
接下来,如果name和email值全部有效,没有error的情况下,则向后端请求'/sendEmail'接口
// send email
if (!error) {
let {
status,
data: { code, msg }
} = await this.$axios.post('/sendEmail', {
name: this.ruleForm.name,
email: this.ruleForm.email
});
}
在后端sendEmail路由的写法,首先在body接收email和name,之后调用nodemailer.createTransport生成一个邮件socket,这里的STMP_CODE需要在邮箱中设置开启STMP转发服务时开启。接下来设置ejs的template ,全部是固定写法,向ejs中输入name,code,date三个变量。之后生成mailOptions 发送选项,其中html为之前生成的ejs模板,attachments为本地的图片,注意每个图片以cid属性来作为唯一的标识,这里我设置了cid: 'welcome',在ejs中可以以<img src="cid:welcome">形式来引用,之后通过 transporter.sendMail来发送邮件,最后根据发送成功服务器后的回调函数设置redis的哈希键值,这里用email:${name}
的形式来作为每一个用户的唯一id,当用户在注册时会调取这个键值,来判断验证码是否正确以及是否过期
router.post('/sendEmail', async (ctx) => {
let { email , name } = ctx.request.body
let transporter = nodemailer.createTransport({
service: 'qq',
port: 465, // SMTP 端口
secureConnection: true, // 使用了 SSL
auth: {
user: '’123456@qq.com',
pass: STMP_CODE,
}
})
//ejs inside template
const template = ejs.compile(fs.readFileSync(path.resolve(__dirname, '../views/email.ejs'), 'utf8'));
let code = Math.random().toString().slice(2, 6)
const html = template({
name,
code,
date: new Date().toLocaleDateString()
});
let mailOptions = {
from: '美妆小铺古风版 123456@qq.com',
to: email,
subject: 'Hello',
html,
attachments: [{
filename: 'welcome.jpg',
path: path.resolve(__dirname, '../views/welcome.jpg'),
cid: 'welcome'
}]
}
let err = ''
await transporter.sendMail(mailOptions, (error, info) => {
err = error
});
if (err) {
ctx.body = {
code: 4004,
msg: err
}
} else {
redis.hmset(`email:${name}`, 'name', name, 'code', code, 'max-age', 600000, 'startTime', new Date().getTime())
ctx.body = {
code: 2000,
msg: "邮件已发送,验证码十分钟内有效"
}
}
})
ejs模板编写的十分简单
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="warpper">
<div class="body">
<img src="cid:welcome">
<p class="title">尊敬的
<%= name %> 您好!</p>
<p class="welcome">欢迎您加入美妆小铺</p>
<p class="code">验证码:
<%= code %>
</p>
<p class="thank">感谢您对美妆小铺的关注与支持!</p>
<p class="time">
<%= date %>
</p>
</div>
</div>
</body>
</html>
网友评论